Java 项目仅在调整窗口大小后出现

Posted

技术标签:

【中文标题】Java 项目仅在调整窗口大小后出现【英文标题】:Java items appear only after the window is resize 【发布时间】:2012-02-04 22:29:15 【问题描述】:

我在一个框架中有 2 个 JPanel。第一个面板包含按钮等 Java 项目。我添加的两个按钮出现,但 JSpinner 在我调整窗口大小后出现。我想这也会发生在我要添加的其他项目上。我该如何解决这个问题?

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerListModel;
import javax.swing.SpinnerNumberModel;

public class StartingPoint 

static JFrame window;
static DrawingArea draw;
static JButton b1, b2;
static JPanel userInt;
static JSpinner gravitySpinner;

public static void main(String[] args) 
    window = new JFrame("Ball");
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setSize(600, 400);
    window.setLayout(new BorderLayout());
    window.setVisible(true);

    draw = new DrawingArea();
    window.add(draw, BorderLayout.CENTER);

    userInt = new JPanel();
    window.add(userInt, BorderLayout.NORTH);

    b1 = new JButton("Start");
    b2 = new JButton("aaa");
    b1.addActionListener(new ActionListener() 
        @Override
        public void actionPerformed(ActionEvent e) 
            draw.setUp();
        
    );
    userInt.add(b1);
    userInt.add(b2);


    SpinnerNumberModel gravityModel = new SpinnerNumberModel(.9, .1, 2, .1);
    gravitySpinner = new JSpinner(gravityModel);
    userInt.add(gravitySpinner);


【问题讨论】:

【参考方案1】:

在 JFrame 上调用 setVisible(true) 之后,您正在向 GUI 添加组件,这是倒退的,因为您在添加任何内容之前渲染 GUI,因此添加的东西是有意义的在全部重新绘制之前,稍后将不会显示。

相反,首先添加所有组件,然后然后通过在 JFrame 上调用 setVisible(true) 来呈现 GUI。

编辑 此外,您应该避免在任何事情上调用setSize(...),而是让组件使用它们的preferredSizes 来调整自己的大小,并在使用setVisible(true) 显示之前在JFrame 上调用pack()

编辑 2 例如:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;

public class StartingPoint 

   private DrawingArea draw;
   private JButton b1, b2;
   private JPanel userInt;
   private JSpinner gravitySpinner;

   private JPanel mainPanel = new JPanel();

   public StartingPoint() 
      mainPanel.setLayout(new BorderLayout());
      draw = new DrawingArea();
      mainPanel.add(draw, BorderLayout.CENTER);

      userInt = new JPanel();
      mainPanel.add(userInt, BorderLayout.NORTH);

      b1 = new JButton("Start");
      b2 = new JButton("aaa");
      b1.addActionListener(new ActionListener() 
         @Override
         public void actionPerformed(ActionEvent e) 
            draw.setUp();
         
      );
      userInt.add(b1);
      userInt.add(b2);

      SpinnerNumberModel gravityModel = new SpinnerNumberModel(.9, .1, 2, .1);
      gravitySpinner = new JSpinner(gravityModel);
      userInt.add(gravitySpinner);
   

   public JPanel getMainPanel() 
      return mainPanel;
   

   public static void main(String[] args) 
      SwingUtilities.invokeLater(new Runnable() 
         public void run() 
            JFrame window = new JFrame("Ball");
            window.add(new StartingPoint().getMainPanel());
            window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            window.pack();
            window.setLocationRelativeTo(null);
            window.setVisible(true);
         
      );
   


class DrawingArea extends JPanel 

   private static final int PREF_W = 600;
   private static final int PREF_H = 400;

   public void setUp() 
      // TODO finish
   

   @Override
   public Dimension getPreferredSize() 
      return new Dimension(PREF_W, PREF_H);
   


【讨论】:

并且您想在 EventQueue.invokeLater() 调用中将所有代码包装在 main 方法中以尊重 Swing threading policy 我应该将我的所有代码从 main 方法中的 run 方法和 main 方法中添加,我必须添加这个 $SwingUtilities.invokeLater(new StartingPoint()); ? @Alex:您将摆脱上面代码中的 everything 静态,在类本身中创建您的 JPanel gui,然后在您的主要创建一个 Runnable 来初始化您的类,将类的 JPanel 添加到 JFrame,然后显示 JFrame。例如,请参阅上面的编辑 2 我在edit2中进行了更改,但现在它不起作用线程“AWT-EventQueue-0”java.lang.***Error中的异常。我应该创建一个新线程还是什么?再次感谢您。 你的意思是 *** 上的一个新线程吗?是的,可能因为这是一个新问题。闻起来好像你在递归地做某事,比如让一个方法调用自己或调用一个类自己的构造函数。【参考方案2】:

在末尾添加setVisible(true) 即可。

【讨论】:

以上是关于Java 项目仅在调整窗口大小后出现的主要内容,如果未能解决你的问题,请参考以下文章

仅在窗口调整大小时防止 div 重叠(带样式组件)

调整框架(窗口)大小后组件消失

使用 JavaScript 更改 Highcharts 的高度。默认情况下,仅在窗口重新调整大小时重新调整大小

WPF:调整图像大小,但仅在用户调整UI大小时

多个 Google 地图和引导选项卡仅在窗口调整大小时呈现

JQuery:如何仅在完成调整大小后才调用 RESIZE 事件?