[英]Why is the JFrame transparent?
我有一个正在起作用的JFrame。 如果我只是将JFrame设置为visible,那么整个JFrame都会出现,但是如果我在将JFrame设置为visible之后尝试执行任何操作,则JFrame将出现,但是是透明的,只有标题和close选项可见。 这只是最近才发生,我不知道发生了什么...
可见的JFrame
GUI frame = new GUI(); //GUI is a class that extends JFrame
frame.setVisible(true);
透明的JFrame
GUI frame = new GUI(); //GUI is a class that extends JFrame
frame.setVisible(true);
frame.setVisible(false); //If I throw a breakpoint here, as soon as it goes from .setVisible(true) to this line, the GUI appears, but is transparent
码
public class GUI extends JFrame {
private JPanel contentPane;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
GUI frame = new GUI();
frame.setVisible(true);
frame.setVisible(false);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public GUI() {
setTitle("Title");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 330, 250);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
}
}
图片
问题可能在这里:
frame.setVisible(false); // If I throw a breakpoint here, as soon as it goes from
// .setVisible(true) to this line, the GUI appears,
// but is transparent
通过在运行Swing代码中设置断点,可以阻止Swing事件线程,从而阻止GUI绘画或与用户进行交互。 如果您需要在运行时调试GUI,可以采取不同的方法来解决,包括使用记录器在运行时记录程序的状态。
编辑
您发表评论:
我希望用户在应用程序继续前进之前完成选择设置。 所以我实际上不是在使用一阵(true),而是一阵(可见)。 visible是一个布尔值,当用户单击gui上的按钮时,该布尔值将设置为false,它将退出循环。
然后,解决方案将完全不同且非常简单:不要使用第二个JFrame来显示此设置显示窗口,而是您将要使用模式 JDialog或JOptionPane(实际上只不过是专用的模式JDialog而已)。
为什么这样做有帮助,是因为Swing具有一种用于模式对话框的特殊机制,该机制在将对话框设置为可见后立即冻结在调用窗口中的代码流。 因此,调用代码将始终知道对话框何时不再可见,因为仅当对话框不可见时,其代码的程序流才会恢复。 因此,您需要在将对话框或JOptionPane设置为可见的那一行之后的行中提取对话框窗口的数据。 并且在您放弃JOptionPanes过于简单化之前,请了解它们的第二个参数,Object类型的对象可以将任何Swing GUI组件作为参数,包括一个包含非常大而复杂的GUI的JPanel,这使这些工具非常有用。
编辑2
您发表评论:
我将WindowsBuilder用于与GUI有关的事情,以使事情变得更容易。 不幸的是,它不提供使用JOptionPane的选项。 也没有JDialogue。 我想继续使用WindowsBuilder能够修改的路线。
在理解底层库之后,我不会再谈论为什么避免使用代码生成工具很重要的原因了,但是我还是建议您检查一下WindowBuilder工具是否可以创建一个扩展JPanel的类。 如果是这样,那么执行此操作,创建您的JPanel,然后在调用代码中,只需将您的JPanel填充到JOptionPane或模式JDialog中即可。
编辑3
例如,假设您有一个名为GetInfoPanel
的JPanel,它允许用户输入一些文本并选择JRadioButton:
class GetInfoPanel extends JPanel {
public static final String[] COLOR_STRINGS = {"Red", "Green", "Blue", "Orange"};
private JTextField infoField = new JTextField(10);
private ButtonGroup buttonGroup = new ButtonGroup();
public GetInfoPanel() {
JPanel topPanel = new JPanel();
topPanel.add(new JLabel("Information that you want to submit:"));
topPanel.add(infoField);
JPanel colorPanel = new JPanel(new GridLayout(1, 0, 5, 0));
for (String colorString : COLOR_STRINGS) {
JRadioButton radioButton = new JRadioButton(colorString);
radioButton.setActionCommand(colorString);
buttonGroup.add(radioButton);
colorPanel.add(radioButton);
}
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(topPanel);
add(colorPanel);
}
public String getInfo() {
return infoField.getText();
}
public String getColorString() {
String selection = "";
ButtonModel model = buttonGroup.getSelection();
if (model != null) {
selection = model.getActionCommand();
}
return selection;
}
}
然后,一个调用类可以创建上述实例,并将其打包并显示在JOptionPane中,然后提取其中包含的信息:
public void actionPerformed(ActionEvent e) {
// create our GetInfoPanel
GetInfoPanel getInfoPanel = new GetInfoPanel();
// display it in a JOptionPane which is a modal JDialog
JOptionPane.showMessageDialog(TestGetInfo.this, getInfoPanel,
"Enter Information Please", JOptionPane.PLAIN_MESSAGE);
// this code will not be called until the dialog above is no longer visible
// extract the text from the getInfoPanel's text field
String info = getInfoPanel.getInfo();
infoDisplayField.setText(info);
// extract the the radiobutton selection from the getInfoPanel
String colorString = getInfoPanel.getColorString();
colorStringField.setText(colorString);
}
您可以在以下程序中对此进行测试:
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class TestGetInfo extends JPanel {
private JTextField infoDisplayField = new JTextField(10);
private JTextField colorStringField = new JTextField(10);
private JButton displayGetInfoBtn = new JButton(new DisplayGetInfoAction(
"Get Info"));
public TestGetInfo() {
infoDisplayField.setFocusable(false);
colorStringField.setFocusable(false);
add(new JLabel("Info:"));
add(infoDisplayField);
add(Box.createHorizontalStrut(10));
add(new JLabel("Color:"));
add(colorStringField);
add(Box.createHorizontalStrut(10));
add(displayGetInfoBtn);
}
private class DisplayGetInfoAction extends AbstractAction {
public DisplayGetInfoAction(String name) {
// this will be the button's text:
super(name);
}
@Override
public void actionPerformed(ActionEvent e) {
// create our GetInfoPanel
GetInfoPanel getInfoPanel = new GetInfoPanel();
// display it in a JOptionPane which is a modal JDialog
JOptionPane.showMessageDialog(TestGetInfo.this, getInfoPanel,
"Enter Information Please", JOptionPane.PLAIN_MESSAGE);
// this code will not be called until the dialog above is no longer visible
// extract the text from the getInfoPanel's text field
String info = getInfoPanel.getInfo();
infoDisplayField.setText(info);
// extract the the radiobutton selection from the getInfoPanel
String colorString = getInfoPanel.getColorString();
colorStringField.setText(colorString);
}
}
private static void createAndShowGui() {
TestGetInfo mainPanel = new TestGetInfo();
JFrame frame = new JFrame("TestGetInfo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
@SuppressWarnings("serial")
class GetInfoPanel extends JPanel {
public static final String[] COLOR_STRINGS = {"Red", "Green", "Blue", "Orange"};
private JTextField infoField = new JTextField(10);
private ButtonGroup buttonGroup = new ButtonGroup();
public GetInfoPanel() {
JPanel topPanel = new JPanel();
topPanel.add(new JLabel("Information that you want to submit:"));
topPanel.add(infoField);
JPanel colorPanel = new JPanel(new GridLayout(1, 0, 5, 0));
for (String colorString : COLOR_STRINGS) {
JRadioButton radioButton = new JRadioButton(colorString);
radioButton.setActionCommand(colorString);
buttonGroup.add(radioButton);
colorPanel.add(radioButton);
}
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(topPanel);
add(colorPanel);
}
public String getInfo() {
return infoField.getText();
}
public String getColorString() {
String selection = "";
ButtonModel model = buttonGroup.getSelection();
if (model != null) {
selection = model.getActionCommand();
}
return selection;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.