2011-08-31 81 views
6

我在這裏花了一段時間閱讀和試驗,想出了一些方法,但沒有得到任何完整的工作,所以我想知道更多有經驗的Swing程序員會做什麼。如何在JPanel上疊加,調整大小和中心組件?

我的應用程序的主窗口包含JPanel的自定義子類型,它用於顯示從數學函數計算出的圖像。這可能需要一些時間來計算,所以在發生這種情況時,我會在面板的中間顯示一條文本消息和一個進度條。當面板調整大小時,我希望文本和進度條適當調整大小,可能使用面板寬度的恆定分數。

此刻我有另一個包含文本和進度條的JPanel子類型,我將這個「進度面板」添加到主面板,並將其設置爲在需要時可見。主面板不包含任何其他組件,但具有自己的paintComponent()方法來顯示從另一個類獲得的BufferedImage。這裏有幾個問題:

  • 進度面板在應該是不是總是可見的,也許是因爲在代碼中沒有明確確保它被繪製在圖像前面。
  • 進度面板始終佔用應用程序面板的整個寬度。它在主面板中使用BoxLayout進行垂直居中,在進度面板之前和之後使用一些垂直膠水,但我沒有設法使相同的技巧水平工作,並且無論如何,進度面板的首選水平大小爲不一定是對的。幾乎可行的一種方法是在進度面板上使用帶有水平和垂直支柱的BorderLayout,但進度面板的大小仍然不正確,並且在調整主面板大小時需要更改支柱。

那麼你會怎麼做?

  • 在主面板中使用不同的佈局管理器?
  • 以某種方式使用LayeredPane或OverlayLayout?
  • 將更多圖層添加到包含圖像面板和進度面板的包容層次結構中?
  • 以上的一些組合,還是別的?

如何調整文本大小。當面板調整大小時是否需要顯式創建新的字體,還是有任何方法可以更自動地執行此操作? -

+0

好的問題+1 – mKorbel

+0

恕我直言,這是不是典型的如在一個窗口中的控件的大小以縮放字體大小。不是說這肯定是個壞主意,但是這絕對不是擺在Swing中的。不過,鑑於顯示器尺寸的多樣性,我很欣賞UI,它允許在現代瀏覽器中改變文本大小。所以它可能是一個單獨的功能,你可以在這部分後工作:CTRL +/-改變字體大小。 –

回答

2

我知道這是一個佈局問題,但如果您有有用的臨時結果,SwingWorker可能會使問題變得更簡單。我有時從這個example開始。

+0

謝謝。我已經使用'SwingWorker'來計算圖像並設置進度條的值。在某些時候,我希望在創建時呈現不完整的圖像。這只是一個玩具項目,我正在使用它來提高我對Swing的瞭解。 – Ben

+0

很好的例子。 :-) – trashgod

3

JProgressBar的首選尺寸由UI委託人BasicProgressBarUI指定。下面的例子說明了各種佈局管理器的效果。 FlowLayout只需使用UIManager默認,ProgressBar.horizontalSize,而GridLayoutBorderLayout.CENTER填充可用空間。 BoxLayout,帶有側面膠水,在框架調整大小時按比例調整。

我已經使用SwingWorker

SwingWorker應該是安全的process()方法更新GUI。您可以更改圖層或者刪除組件,但是我會對任何過於複雜的事情保持警惕。

PreogressTest

附錄:下面是相關的默認值。

System.out.println(UIManager.get("ProgressBar.horizontalSize")); 
 
javax.swing.plaf.DimensionUIResource[width=146,height=12] 

代碼:

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.EventQueue; 
import java.awt.FlowLayout; 
import java.awt.GridLayout; 
import java.awt.LayoutManager; 
import javax.swing.BorderFactory; 
import javax.swing.Box; 
import javax.swing.BoxLayout; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JProgressBar; 

/** @see http://stackoverflow.com/questions/7256775 */ 
public class ProgressTest { 

    private static final Color border = Color.gray; 

    private static void display() { 
     JFrame f = new JFrame("ProgressTest"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setLayout(new GridLayout(0, 1)); 
     f.add(createPanel(new FlowLayout())); 
     f.add(createPanel(new GridLayout())); 
     f.add(createPanel(new BorderLayout())); 

     JPanel p = new JPanel(); 
     p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS)); 
     p.setBorder(BorderFactory.createLineBorder(border)); 
     JProgressBar jpb = new JProgressBar(); 
     p.add(Box.createHorizontalGlue()); 
     p.add(jpb); 
     p.add(Box.createHorizontalGlue()); 
     jpb.setIndeterminate(true); 
     f.add(p); 

     f.pack(); 
     f.setSize(320, 240); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    private static JPanel createPanel(LayoutManager layout) { 
     JPanel p = new JPanel(); 
     p.setBorder(BorderFactory.createLineBorder(border)); 
     p.setLayout(layout); 
     JProgressBar jpb = new JProgressBar(); 
     jpb.setIndeterminate(true); 
     p.add(jpb); 
     return p; 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       display(); 
      } 
     }); 
    } 
}