繁体   English   中英

为什么JFrame是透明的?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM