【问题标题】:Why is my simple JFrame displaying weird?为什么我的简单 JFrame 显示很奇怪?
【发布时间】:2011-03-08 11:34:38
【问题描述】:

我是 Java Swing/AWT 的新手,我在为一个简单的 PopUp 对话框工作后编写了这段代码,该对话框在任何被点击的 JButton 上关闭,但显示的确实很不稳定。有人对修复什么以及如何修复有建议吗?

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.Box.Filler;


public class UpgradePopupWindow extends JPanel implements ActionListener {
//public static UpgradePopupWindow mainWindow;

static final long serialVersionUID = 0;


final String upgrade = "Continue Upgrade";
final String restore = "Restore";

JPanel panels;
JButton flashMe;
JButton helpMe;
JTextArea Message;
JFrame newFrame;
FlasherThread flash;


protected JTextArea addText(String text, boolean visible, int fontStyle) {

    JTextArea textArea = new JTextArea(text);

    textArea.setFont(new Font("SansSerif", fontStyle, 12)); //$NON-NLS-1$

    textArea.setLineWrap(true);
    textArea.setWrapStyleWord(true);
    textArea.setEditable(false);
    textArea.setBackground(Color.DARK_GRAY);
    textArea.setForeground(Color.WHITE);
    textArea.setOpaque(false);
    textArea.setVisible(visible);
    textArea.setAlignmentX(Component.CENTER_ALIGNMENT);

    add(textArea);

    return textArea;
}

private UpgradePopupWindow(JFrame frame, Object ft) {

    flash = (FlasherThread)ft;
    String text = "An error occurred during the attempt to update your  software. We recommend the following: (1) Restore your device to its previous version, (2) back up important data, and then (3) try updating your device again. If you continue with the current update, only your previously backed-up data will be available.";
    addFiller(5);
    addLabel(text, Font.PLAIN, 12);
    //addText(text, true, Font.PLAIN);
    addFiller(20);
    newFrame = frame;
    flashMe = new JButton(upgrade);

    flashMe.setActionCommand("upgrade");
    flashMe.addActionListener(this);
    flashMe.setEnabled(true);
    add(flashMe);


    helpMe = new JButton(restore);
    helpMe.setActionCommand("restore");
    helpMe.addActionListener(this);
    helpMe.setEnabled(true);
    add(helpMe);
    setOpaque(true);
    newFrame.setContentPane(this);
}

protected JLabel addLabel(String text, int fontStyle, int size) {
    JLabel label = new JLabel(text);
    label.setFont(new Font("SansSerif", fontStyle, size)); 
    label.setAlignmentX(Component.CENTER_ALIGNMENT);
    label.setOpaque(false);
    label.setVisible(true);
    //label.setForeground(Color.BLUE);

    add(label);
    return label;
}

protected void addFiller(int size) {
    /*
     * create some space before the progress bar
     */
    Dimension diminsion = new Dimension(size, size);
    Filler filler = new Filler(diminsion, diminsion, diminsion);
    filler.setAlignmentX(Component.CENTER_ALIGNMENT);

    add(filler);
}

public static void createGUI(Object obj) {
    //Create and set up the frame.
   JFrame frame = new JFrame("PopUp Dialog");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setPreferredSize(new Dimension(400, 200));
    //create and setup the content pane
    UpgradePopupWindow popUpContentPane = new UpgradePopupWindow(frame, obj);

    popUpContentPane.setOpaque(true);
    frame.setContentPane(popUpContentPane);

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

}


public void actionPerformed(ActionEvent e) {

    if("restore".equals(e.getActionCommand())) {
        System.out.println("restore button selected");
        flash.setUpgradeRestoreChoice("restore");
        newFrame.dispose();
    } else if ("upgrade".equals(e.getActionCommand())) {
        System.out.println("upgrade button selected");
        flash.setUpgradeRestoreChoice("upgrade");
        newFrame.dispose();
    }
}

}alt text

【问题讨论】:

  • 你能描述一下它是如何显示奇怪的吗?最好附上图片。
  • 就像我刚刚附上的那个截图

标签: java swing awt jframe jbutton


【解决方案1】:

我没有看到您使用任何类型的布局。 Swing 设计适用于布局,然后用这些布局内的项目填充您的容器。我个人最喜欢使用的布局是MigLayout

网页上有很多支持。一旦你开始使用布局,你的工作就会变得轻松很多。

【讨论】:

  • 我几乎不了解 BoxLayout,您能否详细说明如何在此设置中引入任何类型的布局?
【解决方案2】:

不需要更改框架的contentPane。您可以将 JPanel 添加到框架中。它会默认填充框架。

JLabel 不自动换行。

一种选择是手动插入换行符。 JLabel 接受 HTML 的子集:

String text = "<html>An error occurred during the attempt to update your  software. <br />We recommend the following:<br />(1) Restore your device to its previous version,<br />(2) back up important data, and then<br />(3) try updating your device again.<br />If you continue with the current update, only your previously backed-up data will be available.</html>";

另一种选择是使用JTextArea 代替标签。它不接受 HTML,但可以自动换行,您可以在文本中包含换行符以强制换行。

不要忘记移除边框并使背景透明(调用setOpaque(false) 仅适用于某些外观,不适用于其他外观。)

无论哪种方式,您都需要在 JPanel 上设置布局。

这是一个使用 GridBagLayout 的示例:

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.WindowConstants;
import javax.swing.Box.Filler;


public class UpgradePopupWindow extends JPanel implements ActionListener {
//public static UpgradePopupWindow mainWindow;

static final long serialVersionUID = 0;


final String upgrade = "Continue Upgrade";
final String restore = "Restore";

JPanel panels;
JButton flashMe;
JButton helpMe;
JTextArea Message;
JFrame newFrame;
FlasherThread flash;


protected JTextArea addText(String text, boolean visible, int fontStyle) {

    JTextArea textArea = new JTextArea(text);

    textArea.setFont(new Font("SansSerif", fontStyle, 12)); //$NON-NLS-1$

    textArea.setLineWrap(true);
    textArea.setWrapStyleWord(true);
    textArea.setEditable(false);
    textArea.setBackground(Color.DARK_GRAY);
    textArea.setForeground(Color.WHITE);
    textArea.setOpaque(false);
    textArea.setVisible(visible);
    textArea.setAlignmentX(Component.CENTER_ALIGNMENT);

    add(textArea);

    return textArea;
}

protected JTextArea addMultiLineLabel(String text, int fontStyle, int fontSize, Object constraints) {

    JTextArea textArea = new JTextArea(text);

    textArea.setFont(new Font("SansSerif", fontStyle, fontSize));

    textArea.setLineWrap(true);
    textArea.setWrapStyleWord(true);
    textArea.setEditable(false);
    textArea.setBackground(new Color(0, 0, 0, 0)); // Zero alpha = transparent background
    textArea.setOpaque(false);
    textArea.setBorder(null);
    textArea.setAlignmentX(Component.CENTER_ALIGNMENT);

    add(textArea, constraints);

    return textArea;
}


private UpgradePopupWindow(JFrame frame, Object ft) {

    super(new GridBagLayout());
    GridBagConstraints gbc = new GridBagConstraints();
    flash = (FlasherThread)ft;
    String text = "An error occurred during the attempt to update your  software.\nWe recommend the following:\n (1) Restore your device to its previous version,\n (2) back up important data, and then\n (3) try updating your device again.\nIf you continue with the current update, only your previously backed-up data will be available.";
    addFiller(5);
    gbc.gridy = 0;
    gbc.gridx = 0;
    gbc.gridwidth = 2;
    gbc.weightx = 1.0;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    addMultiLineLabel(text, Font.PLAIN, 12, gbc);
    addFiller(20);
    newFrame = frame;

    gbc.gridy = 1;
    gbc.gridwidth = 1;
    gbc.fill = GridBagConstraints.NONE;
    flashMe = new JButton(upgrade);
    flashMe.setActionCommand("upgrade");
    flashMe.addActionListener(this);
    flashMe.setEnabled(true);
    add(flashMe, gbc);

    ++ gbc.gridx;
    helpMe = new JButton(restore);
    helpMe.setActionCommand("restore");
    helpMe.addActionListener(this);
    helpMe.setEnabled(true);
    add(helpMe, gbc);
    setOpaque(true);
    newFrame.add(this);
}

protected JLabel addLabel(String text, int fontStyle, int size) {
    JLabel label = new JLabel(text);
    label.setFont(new Font("SansSerif", fontStyle, size)); 
    label.setAlignmentX(Component.CENTER_ALIGNMENT);
    label.setOpaque(false);
    label.setVisible(true);
    //label.setForeground(Color.BLUE);

    add(label);
    return label;
}

protected void addFiller(int size) {
    /*
     * create some space before the progress bar
     */
    Dimension diminsion = new Dimension(size, size);
    Filler filler = new Filler(diminsion, diminsion, diminsion);
    filler.setAlignmentX(Component.CENTER_ALIGNMENT);

    add(filler);
}

public static void createGUI(Object obj) {
    //Create and set up the frame.
   JFrame frame = new JFrame("PopUp Dialog");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setPreferredSize(new Dimension(400, 200));
    //create and setup the content pane
    UpgradePopupWindow popUpContentPane = new UpgradePopupWindow(frame, obj);

    popUpContentPane.setOpaque(true);
    frame.setContentPane(popUpContentPane);

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

}


public void actionPerformed(ActionEvent e) {

    if("restore".equals(e.getActionCommand())) {
        System.out.println("restore button selected");
        flash.setUpgradeRestoreChoice("restore");
        newFrame.dispose();
    } else if ("upgrade".equals(e.getActionCommand())) {
        System.out.println("upgrade button selected");
        flash.setUpgradeRestoreChoice("upgrade");
        newFrame.dispose();
    }
}

}

【讨论】:

  • 这很好,虽然我还有另一个问题。什么控制此对话框的背景颜色?我想要默认的灰色/浅灰色默认背景颜色。
  • 另外,有没有办法对文本进行规范化,使 JTextArea 的左右边框与对话框边缘均匀且等距?
  • 这里有一些建议:stackoverflow.com/questions/200106/…
  • 在 JTextArea 中更改文本对齐稍微复杂一些。见forums.sun.com/thread.jspa?threadID=5233132
  • 有没有更好的方法来实现这个解决方案,布局更简单,避免使用 GridBagLayout?
【解决方案3】:
  1. 您应该使用比默认更好的布局管理器
  2. 您应该使用JOptionPane 而不是制作自己的选项对话框

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-30
    • 1970-01-01
    • 2021-06-01
    相关资源
    最近更新 更多