2016-05-20 47 views
0

enter image description here的Java Swing搬走从空布局

我利用在空布局皱起眉头(我定义了很多常量和使用的窗口大小调整监听器,以方便)建立了一个伟大的GUI。一切工作完美,直到我开始使用新的电脑。现在,组件位置不正确(从图片中可以看到组件向右偏移)。在研究了这个问题之后,我了解到布局管理器确保组件在不同的机器上正确定位。因此,我想开始在实际的布局管理器中重建GUI。问题在于,当我尝试使用实际的布局管理器时,我定位组件的方式经常会受到限制。

对于任何一个好奇的人,我最初使用的是windows 10的戴尔inspiron笔记本电脑,并转移到华硕笔记本电脑(我不知道实际的型号,但触摸屏可以从键盘上分离),也与Windows 10

我的问题:

哪些布局管理器是最快和最容易构建在上面的图片中显示的GUI(出股票的Swing布局别人的)。我希望这种布局能够尊重组件的实际尺寸,但仅限于少数组件,而不是全部组件。使用这种布局,我将如何定位库存按钮(左下角的锤子),以使库存按钮的左下角与容器的左下角相距5像素,即使在调整大小后容器?

在此先感谢。所有的帮助表示赞赏。

编辑:“去找钥匙”和“试图强行开门”选项应该有他们的大小的尊重。

+1

哪个组件的首选大小应该得到尊重?我想到的最简单的解决方案是主面板的“BorderLayout”。将textarea添加到'NORTH'。制作另一个包含库存按钮('WEST')和位置标签('EAST')的'BorderLayout'。将其添加到主“BorderLayout”的“SOUTH”中。然后,将一个“BoxLayout”垂直对齐到包含两个文本框的主BorderLayout的“CENTER”中。标准版面管理器的[总结](https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html)。 –

+1

关于唯一能够完成UI的布局是'GridBagLayout'和'GroupLayout'。后者通常旨在供IDE中的GUI生成器使用。除了这两个,我通常会将布局结合起来,为UI的每个部分使用最佳布局。对于底部部分,我将使用带有“BorderLayout”的单个面板,并将该图标添加到“LINE_START”,并将标签添加到“LINE_END”。要获得5px缩进,请使用底部面板上的'EmptyBorder'。 –

+0

不要指望它,不要把你的鸡蛋放在一个篮子 - 咆哮的狗会在这里吠叫,但在几年后,你会回来“哦,我的Windows 11不运行这个东西!” – gpasch

回答

3

我想到的最简单的解决方案是用于主面板的BorderLayout。将textarea添加到NORTH/PAGE_START。制作包含库存按钮(WEST/LINE_START)和位置标签(EAST/LINE_END)的另一个BorderLayout。加上SOUTH/PAGE_END的主BorderLayout。然后只需添加一个BoxLayout垂直对齐主BorderLayoutCENTER包含两个按钮。 Here's a tutorial为标准布局管理器。


enter image description here

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Insets; 
import java.awt.image.BufferedImage; 

import javax.swing.BorderFactory; 
import javax.swing.Box; 
import javax.swing.BoxLayout; 
import javax.swing.ImageIcon; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JTextArea; 

public class Example { 

    public Example() { 
     JTextArea textArea = new JTextArea("There is a locked door"); 
     textArea.setRows(5); 
     textArea.setBorder(BorderFactory.createLineBorder(Color.GRAY)); 
     textArea.setEditable(false); 

     WhiteButton button1 = new WhiteButton("Go find a key") { 
      @Override 
      public Dimension getMinimumSize() { 
       return new Dimension(200, 25); 
      } 

      @Override 
      public Dimension getPreferredSize() { 
       return new Dimension(200, 25); 
      } 

      @Override 
      public Dimension getMaximumSize() { 
       return new Dimension(200, 25); 
      } 
     }; 
     WhiteButton button2 = new WhiteButton("Attempt to force the door open"); 
     button2.setMargin(new Insets(0, 60, 0, 60)); 

     JPanel buttonPanel = new JPanel(); 
     buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS)); 
     buttonPanel.add(button1); 
     buttonPanel.add(Box.createVerticalStrut(5)); 
     buttonPanel.add(button2); 

     WhiteButton inventoryButton = new WhiteButton(
       new ImageIcon(new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB))); 

     JLabel locationLabel = new JLabel("Location: 0"); 
     locationLabel.setVerticalAlignment(JLabel.BOTTOM); 

     JPanel southPanel = new JPanel(new BorderLayout()); 
     southPanel.add(inventoryButton, BorderLayout.WEST); 
     southPanel.add(locationLabel, BorderLayout.EAST); 

     JPanel mainPanel = new JPanel(new BorderLayout(0, 5)); 
     mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 
     mainPanel.add(textArea, BorderLayout.NORTH); 
     mainPanel.add(buttonPanel); 
     mainPanel.add(southPanel, BorderLayout.SOUTH); 

     JFrame frame = new JFrame("Example"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setContentPane(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Example(); 
      } 
     }); 
    } 

    private class WhiteButton extends JButton { 

     public WhiteButton() { 
      setBackground(Color.WHITE); 
     } 

     public WhiteButton(String text) { 
      this(); 
      setText(text); 
     } 

     public WhiteButton(ImageIcon icon) { 
      this(); 
      setIcon(icon); 
      setBorder(BorderFactory.createLineBorder(Color.GRAY)); 
     } 

    } 

} 
+0

你的例子很好,但我不知道如何让布局尊重“去找钥匙”和“试图强制开门”按钮的大小。我试图设置这些组件的最大,最小和首选大小,但没有运气。 – olta8

+0

@ olta8通常不建议太多地设置组件的首选大小。我在我的例子中也犯了一个错误:你应该调用像'textArea.setRows(5);'而不是覆盖它的首选大小。您还可以尝试设置按钮的边距,以实现标签和边框之间的希望间隙:'button.setMargin(Insets);'。如果这一切都没有帮助:当我覆盖每个尺寸时,它适用于我。查看我的更新示例,了解此评论中提及的所有内容'button1'具有重写方法,'button2'具有margin方法。 –