为什么前端不是我想要的方式?

Mon*_*rgu -3 java swing jpanel jframe

我想实现这种外观并尝试相应地设置 JPanel 组件,但当我运行应用程序时,我看到了不同的位置。这就是我正在寻找的外观:我的形象目标

但这就是我所拥有的:我的应用程序

首先,顺序不正确,其次,项目之间没有空格,所以总的来说,这不是我想要的。如何修复它以使其看起来与我第一次添加的图像相似?我的代码:

package Lab5;

import java.awt.*;
import javax.swing.*;
import javax.swing.border.Border;

public class FontDesigner extends JFrame {
    public FontDesigner() {
        // JFrame
        setSize(400, 400);
        setTitle("Font Changer");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // String
        JLabel text = new JLabel("Change Me");
        text.setFont(new Font("Arial", 1, 28));

        // Radio Button
        JRadioButton button1 = new JRadioButton("Small");
        JRadioButton button2 = new JRadioButton("Medium");
        JRadioButton button3 = new JRadioButton("Large");
        ButtonGroup radioGroup = new ButtonGroup();
        radioGroup.add(button1);
        radioGroup.add(button2);
        radioGroup.add(button3);

        /*
         * if (button1.isSelected()) {
         * text.setSize(1);
         * }
         */

        // Combo Box
        JComboBox combo = new JComboBox<>();
        combo.addItem("Serif");
        combo.addItem("Sans-Serif");
        // String selectedFont = (String) combo.getSelectedItem();

        // Check Box
        JCheckBox checkBox1 = new JCheckBox("Italic");
        JCheckBox checkBox2 = new JCheckBox("Bold");
        ButtonGroup checkBoxGroup = new ButtonGroup();
        checkBoxGroup.add(checkBox1);
        checkBoxGroup.add(checkBox2);

        // JPanel
        JPanel panel1 = new JPanel();
        JPanel panel2 = new JPanel();
        JPanel panel3 = new JPanel();
        JPanel panel4 = new JPanel();
        panel1.setLayout(new BorderLayout());
        panel2.setLayout(new BorderLayout());
        panel3.setLayout(new BorderLayout());
        panel4.setLayout(new BorderLayout());
        panel1.add(text, BorderLayout.CENTER);
        panel2.add(combo, BorderLayout.CENTER);
        panel3.add(button1, BorderLayout.WEST);
        panel3.add(button2, BorderLayout.CENTER);
        panel3.add(button3, BorderLayout.EAST);
        panel4.add(checkBox1);
        panel4.add(checkBox2);

        // Frame Configuration
        // setLayout(new BorderLayout());
        setLayout(new FlowLayout());
        add(panel1);
        add(panel2);
        add(panel3);
        add(panel4);

        // Set Visibility
        setVisible(true);

    }

    public static void main(String[] args) {
        FontDesigner newFontDesigner = new FontDesigner();
    }
}
Run Code Online (Sandbox Code Playgroud)

Gil*_*anc 5

介绍

我重新排列了您的代码以创建以下 GUI。

图形用户界面

解释

Oracle 有一个有用的教程:使用 Swing 创建 GUI。跳过使用 NetBeans IDE 学习 Swing 部分。

所有 Swing 应用程序都必须从调用该SwingUtilities invokeLater方法开始。此方法确保 Swing 组件在事件调度线程上创建和执行。

我注意到的第一件事是你的 GUI 可以分为四个独立的JPanels. 一根用于保存文本,一根用于保存字体选择,一根用于保存样式,一根用于保存尺寸。

因此,我将您的代码重新排列为四种方法,每种方法都会生成一个JPanels.

然后,我决定文本JPanel可能应该位于JFrame's BorderLayout. 因此,我创建了一个控件JPanelJPanels使用另一个BorderLayout.

在单独的方法中创建每个JPanel管理器使我能够尝试不同的 Swing 布局管理器并查看我最喜欢哪些。它还使其他人更容易阅读和理解代码。

我修改了JComboBox以保存一个AppFont实例。这样,我可以在组合框中显示字体系列名称。当用户选择其中一个选项时,您就有一个Font要移动到该currentFont字段的实例。

代码

这是完整的可运行代码。我将附加类设置为内部类,这样我就可以将代码作为一个块发布。

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;

import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.SwingUtilities;

public class FontDesigner implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new FontDesigner());
    }

    private Font currentFont;

    private JComboBox<AppFont> fontComboBox;

    private JLabel textLabel;

    public FontDesigner() {
        this.currentFont = new Font("Arial", Font.BOLD, 28);
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Font Changer");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(createDisplayPanel(), BorderLayout.CENTER);
        frame.add(createControlPanel(), BorderLayout.SOUTH);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private JPanel createDisplayPanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        textLabel = new JLabel("Change Me");
        textLabel.setFont(currentFont);
        panel.add(textLabel);

        return panel;
    }

    private JPanel createControlPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        panel.add(createFontSelectionPanel(), BorderLayout.NORTH);
        panel.add(createStylePanel(), BorderLayout.CENTER);
        panel.add(createSizePanel(), BorderLayout.SOUTH);

        return panel;
    }

    private JPanel createFontSelectionPanel() {
        JPanel panel = new JPanel(new FlowLayout());

        fontComboBox = new JComboBox<>();
        fontComboBox.addItem(new AppFont(new Font("Arial", Font.BOLD, 28)));
        fontComboBox.addItem(new AppFont(new Font("Dialog", Font.BOLD, 28)));
        fontComboBox.addItem(new AppFont(new Font("Serif", Font.BOLD, 28)));
        panel.add(fontComboBox);

        return panel;
    }

    private JPanel createStylePanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBorder(BorderFactory.createTitledBorder("Style"));

        JCheckBox checkBox2 = new JCheckBox("Bold");
        panel.add(checkBox2);

        JCheckBox checkBox1 = new JCheckBox("Italic");
        panel.add(checkBox1);

        return panel;
    }

    private JPanel createSizePanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBorder(BorderFactory.createTitledBorder("Size"));

        ButtonGroup radioGroup = new ButtonGroup();

        JRadioButton button1 = new JRadioButton("Small");
        radioGroup.add(button1);
        panel.add(button1);

        JRadioButton button2 = new JRadioButton("Medium");
        radioGroup.add(button2);
        panel.add(button2);

        JRadioButton button3 = new JRadioButton("Large");
        radioGroup.add(button3);
        panel.add(button3);

        return panel;
    }

    public class AppFont {

        private final Font font;

        private final String fontName;

        public AppFont(Font font) {
            this.font = font;
            this.fontName = font.getFamily();
        }

        public Font getFont() {
            return font;
        }

        @Override
        public String toString() {
            return fontName;
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

编辑添加1:

我继续通过添加应用程序模型和所有ActionListeners. 我创建了所有ActionListenerslambda 表达式,因为我不打算提供完整的答案。

对于OP,请自行完成GUI。

对于其他人:

我扫描了GraphicsEnvironment所有可能正确显示“Change Me”的字体系列。我的计算机有 218 个符合条件的字体系列。您的计算机可能有一组不同的字体系列。对话框字体应该存在于大多数计算机上,因此我将其设置为默认字体。

我对 GUI 做了一些修改。这是修改后的 GUI。

更新的图形用户界面

代码1

这是完整的可运行代码。我创建了额外的类内部类,这样我就可以将代码作为一个块发布。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GraphicsEnvironment;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.SwingUtilities;

public class FontChanger implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new FontChanger());
    }

    private final FontChangerModel model;

    private JComboBox<AppFont> fontComboBox;

    private JLabel chooseLabel, textLabel;

    public FontChanger() {
        this.model = new FontChangerModel();
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Font Changer");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(createDisplayPanel(), BorderLayout.CENTER);
        frame.add(createControlPanel(), BorderLayout.SOUTH);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private JPanel createDisplayPanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        textLabel = new JLabel(model.getDisplayText());
        updateDisplayPanel();
        panel.add(textLabel);

        Dimension d = panel.getPreferredSize();
        panel.setPreferredSize(new Dimension(d.width + 150, d.height));
        return panel;
    }

    private void updateTextDisplay() {
        Font font = model.getCurrentFont();
        String fontFamily = font.getFamily();
        int fontSizeIndex = model.getCurrentFontSizeIndex();
        model.updateComboBoxModel(fontFamily, model.getCurrentFontStyle(),
                fontSizeIndex);
        updateFontSelectionPanel();
        updateDisplayPanel();
    }

    private JPanel createControlPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        panel.add(createFontSelectionPanel(), BorderLayout.NORTH);
        panel.add(createStylePanel(), BorderLayout.CENTER);
        panel.add(createSizePanel(), BorderLayout.SOUTH);

        return panel;
    }

    private JPanel createFontSelectionPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(0, 0, 20, 0));

        chooseLabel = new JLabel(" ");
        panel.add(chooseLabel, BorderLayout.NORTH);

        panel.add(Box.createVerticalStrut(5), BorderLayout.CENTER);

        fontComboBox = new JComboBox<>(model.getComboBoxModel());
        fontComboBox.addActionListener(event -> {
            AppFont appFont = (AppFont) fontComboBox.getSelectedItem();
            Font font = model.getCurrentFont();
            if (appFont != null) {
                font = appFont.getFont();
            }

            String fontFamily = font.getFamily();
            int fontSizeIndex = model.getCurrentFontSizeIndex();
            model.setCurrentFont(font);
            model.updateComboBoxModel(fontFamily, model.getCurrentFontStyle(),
                    fontSizeIndex);
            updateFontSelectionPanel();
            updateDisplayPanel();
        });
        panel.add(fontComboBox, BorderLayout.SOUTH);

        updateFontSelectionPanel();

        return panel;
    }

    private JPanel createStylePanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBorder(BorderFactory.createTitledBorder("Style"));

        JCheckBox checkBox2 = new JCheckBox("Bold");
        checkBox2.addActionListener(event -> {
            if (checkBox2.isSelected()) {
                model.setBold(true);
            } else {
                model.setBold(false);
            }
            updateTextDisplay();
        });
        panel.add(checkBox2);

        JCheckBox checkBox1 = new JCheckBox("Italic");
        checkBox1.addActionListener(event -> {
            if (checkBox1.isSelected()) {
                model.setItalic(true);
            } else {
                model.setItalic(false);
            }
            updateTextDisplay();
        });
        panel.add(checkBox1);

        return panel;
    }

    private JPanel createSizePanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBorder(BorderFactory.createTitledBorder("Size"));

        ButtonGroup radioGroup = new ButtonGroup();

        JRadioButton button1 = new JRadioButton("Small");
        button1.addActionListener(event -> {
            updateSizePanel(0);
        });
        radioGroup.add(button1);
        panel.add(button1);

        JRadioButton button2 = new JRadioButton("Medium");
        button2.addActionListener(event -> {
            updateSizePanel(1);
        });
        radioGroup.add(button2);
        panel.add(button2);

        JRadioButton button3 = new JRadioButton("Large");
        button3.addActionListener(event -> {
            updateSizePanel(2);
        });
        button3.setSelected(true);
        radioGroup.add(button3);
        panel.add(button3);

        return panel;
    }

    private void updateSizePanel(int fontSizeIndex) {
        Font font = model.getCurrentFont();
        String fontFamily = font.getFamily();
        model.setCurrentFontSizeIndex(fontSizeIndex);
        model.updateComboBoxModel(fontFamily, model.getCurrentFontStyle(),
                fontSizeIndex);
        updateFontSelectionPanel();
        updateDisplayPanel();
    }

    private void updateFontSelectionPanel() {
        DefaultComboBoxModel<AppFont> comboBoxModel = model.getComboBoxModel();
        int size = comboBoxModel.getSize();
        String s = "Choose one of the " + size + " fonts:";
        chooseLabel.setText(s);
        fontComboBox.setSelectedIndex(model.getCurrentFontIndex());
    }

    private void updateDisplayPanel() {
        textLabel.setFont(model.getCurrentFont());
    }

    public class FontChangerModel {

        private boolean isBold, isItalic;

        private final int[] pointSizes;

        private int currentFontIndex, currentFontSizeIndex;

        private final DefaultComboBoxModel<AppFont> comboBoxModel;

        private Font currentFont;

        private final String displayText;

        public FontChangerModel() {
            this.displayText = "Change Me";
            this.currentFontSizeIndex = 2;
            this.isBold = false;
            this.isItalic = false;
            this.pointSizes = new int[] { 16, 32, 48 };
            this.comboBoxModel = new DefaultComboBoxModel<>();
            updateComboBoxModel("Dialog", getCurrentFontStyle(),
                    currentFontSizeIndex);
        }

        public void updateComboBoxModel(String fontFamily, int fontStyle,
                int size) {
            comboBoxModel.removeAllElements();
            GraphicsEnvironment ge = GraphicsEnvironment
                    .getLocalGraphicsEnvironment();
            String[] allFonts = ge.getAvailableFontFamilyNames();

            int fontIndex = 0;
            for (int index = 0; index < allFonts.length; index++) {
                Font font = new Font(allFonts[index], fontStyle,
                        pointSizes[size]);
                if (font.canDisplayUpTo(displayText) < 0) {
                    comboBoxModel.addElement(new AppFont(font));
                    if (allFonts[index].equals(fontFamily)) {
                        currentFont = font;
                        currentFontIndex = fontIndex;
                    }
                    fontIndex++;
                }
            }
        }

        public Font getCurrentFont() {
            return currentFont;
        }

        public void setCurrentFont(Font currentFont) {
            this.currentFont = currentFont;
        }

        public int getCurrentFontIndex() {
            return currentFontIndex;
        }

        public int getCurrentFontSizeIndex() {
            return currentFontSizeIndex;
        }

        public void setCurrentFontSizeIndex(int currentFontSizeIndex) {
            this.currentFontSizeIndex = currentFontSizeIndex;
        }

        public int getCurrentFontStyle() {
            int currentFontStyle = 0;
            if (isBold) {
                currentFontStyle |= 1;
            }
            if (isItalic) {
                currentFontStyle |= 2;
            }

            return currentFontStyle;
        }

        public boolean isBold() {
            return isBold;
        }

        public void setBold(boolean isBold) {
            this.isBold = isBold;
        }

        public boolean isItalic() {
            return isItalic;
        }

        public void setItalic(boolean isItalic) {
            this.isItalic = isItalic;
        }

        public DefaultComboBoxModel<AppFont> getComboBoxModel() {
            return comboBoxModel;
        }

        public String getDisplayText() {
            return displayText;
        }

    }

    public class AppFont {

        private final Font font;

        public AppFont(Font font) {
            this.font = font;
        }

        public Font getFont() {
            return font;
        }

        @Override
        public String toString() {
            return font.getFamily();
        }

    }

}
Run Code Online (Sandbox Code Playgroud)