Build a Beautiful Java Storybook App: Step‑by‑Step Swing Tutorial

This tutorial walks you through creating a Java Swing storybook application, covering UI design, background image handling, event listeners for page navigation, font and color customization, wallpaper switching, and efficient text loading from TXT files using FileInputStream.

Python Crawling & Data Mining
Python Crawling & Data Mining
Python Crawling & Data Mining
Build a Beautiful Java Storybook App: Step‑by‑Step Swing Tutorial

Project Background

With the rise of mobile internet, e‑books have become mainstream; this project aims to present e‑books to users in a targeted way to improve learning efficiency.

Project Goals

Implement an attractive interface.

Provide basic functions to change font size, font family, style, color, and wallpaper, as well as page navigation.

Read TXT files in Java and simplify the code.

Implementation

First, review the previous article that created the window, menu bar, and navigation buttons. The following steps complete the remaining features.

1. Display background image and design the interface

text01.setOpaque(false);
panel01.setOpaque(false);
label.setBounds(0,0,bg.getIconWidth(),bg.getIconHeight()); // set bounds
imagePanel=(JPanel) this.getContentPane(); // get content panel
imagePanel.setOpaque(false); // set transparent
this.getLayeredPane().add(label, new Integer(Integer.MIN_VALUE));

Then add the background image to the lowest layer of the layered pane.

label.setBounds(0,0,bg.getIconWidth(),bg.getIconHeight()); // set bounds
imagePanel=(JPanel) this.getContentPane(); // get content panel
imagePanel.setOpaque(false); // set transparent
this.getLayeredPane().add(label, new Integer(Integer.MIN_VALUE));

2. Add event listener (MyListener)

Implement page‑switching buttons:

class MyListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        // previous page
        if (e.getSource() == btn_last) {
            if (papeNum > 1) {
                papeNum--;
                btn_last.setEnabled(true);
                btn_next.setEnabled(true);
            }
            if (papeNum == 1) {
                btn_last.setEnabled(false);
                btn_next.setEnabled(true);
            }
        }
        // next page
        if (e.getSource() == btn_next) {
            if (papeNum < str.length) {
                papeNum++;
                btn_last.setEnabled(true);
                btn_next.setEnabled(true);
            }
            if (papeNum == str.length) {
                btn_last.setEnabled(true);
                btn_next.setEnabled(false);
            }
        }
        text01.setText(str[papeNum - 1]);
    }
}

Implement font size, family, and style changes:

if (e.getSource() == twelf) size = 12; // size 12
if (e.getSource() == fiveteen) size = 15; // size 15
if (e.getSource() == eighteen) size = 18; // size 18
if (e.getSource() == twenty) size = 20; // size 20
if (e.getSource() == song) style = "宋体"; // SimSun
if (e.getSource() == hei) style = "黑体"; // SimHei
if (e.getSource() == kai) style = "楷体"; // KaiTi
if (e.getSource() == chang) pattern = Font.PLAIN; // regular
if (e.getSource() == jia) pattern = Font.BOLD; // bold
if (e.getSource() == qing) pattern = Font.ITALIC; // italic
text01.setFont(new Font(style, pattern, size));

Implement color changes and wallpaper switching:

if (e.getSource() == red) text01.setForeground(Color.red);
if (e.getSource() == green) text01.setForeground(Color.green);
if (e.getSource() == blue) text01.setForeground(Color.blue);
if (e.getSource() == swap) { // change wallpaper
    photoNum++;
    if (photoNum >= 6) photoNum = 1;
    label.setIcon(new ImageIcon("photo//photo" + photoNum + ".jpg"));
}

3. Read story text from TXT files

FileInputStream is used to read file bytes (suitable for images, videos, etc.).

FileInputStream inStream0 = new FileInputStream("story//s01.txt");
FileInputStream inStream1 = new FileInputStream("story//s02.txt");
FileInputStream inStream2 = new FileInputStream("story//s03.txt");
str[0] = s.readFile(inStream0);
str[1] = s.readFile(inStream1);
str[2] = s.readFile(inStream2);
text01.setText(str[0]);

Method to read file content:

public String readFile(InputStream inStream) {
    byte[] buffer = new byte[2048];
    int hasRead = 0;
    StringBuffer sBuffer = new StringBuffer();
    try {
        while ((hasRead = inStream.read(buffer)) != -1) {
            sBuffer.append(new String(buffer, 0, hasRead, "GBK"));
        }
        inStream.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return sBuffer.toString();
}

4. Why a JLabel can serve as a window background

JFrame hierarchy: JRootPane (bottom), JLayerPane (middle), ContentPane (top). By placing the background image on the JLayerPane and making ContentPane transparent, the image becomes the window background.

Conclusion

The tutorial introduced basic usage of JPanel, JButton, JLabel, JTextArea, JMenu, JMenuItem and related event handling.

Adding event handlers is the main difficulty, requiring understanding of constructors and inner classes.

The code is simple and aims to help readers; the full project code can be obtained by replying with the keyword "故事书".

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaGUIfile I/ODesktop ApplicationSwing
Python Crawling & Data Mining
Written by

Python Crawling & Data Mining

Life's short, I code in Python. This channel shares Python web crawling, data mining, analysis, processing, visualization, automated testing, DevOps, big data, AI, cloud computing, machine learning tools, resources, news, technical articles, tutorial videos and learning materials. Join us!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.