2011-08-31 83 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(); 
      } 
     }); 
    } 
}