2016-05-20 92 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方法。 –