【问题标题】:How to overlay, resize and centre a component on a JPanel?如何在 JPanel 上覆盖、调整组件大小和居中?
【发布时间】:2011-11-07 13:52:40
【问题描述】:

我在这里花了一些时间阅读和试验,并提出了一些方法,但还没有让它们中的任何一个完全起作用,所以我想知道更有经验的 Swing 程序员会做什么。

我的应用程序的主窗口包含 JPanel 的自定义子类型,用于显示从数学函数计算的图像。这可能需要一些时间来计算,所以当发生这种情况时,我会在面板中间显示一条文本消息和一个进度条。我希望在调整面板大小时适当地调整文本和进度条的大小,可能使用面板宽度的恒定分数。

目前我有另一个包含文本和进度条的 JPanel 子类型,我将这个“进度面板”添加到主面板,并在需要时将其设置为可见。主面板不包含任何其他组件,但有自己的 paintComponent() 方法来显示从另一个类获取的 BufferedImage。就目前而言,存在一些问题:

  • 进度面板在应该显示的时候并不总是可见,这可能是因为代码中没有明确确保它被绘制在图像前面的地方。
  • 进度面板始终占据应用程序面板的整个宽度。它在主面板中使用 BoxLayout 垂直居中,在进度面板之前和之后有一些垂直胶水,但我没有设法获得相同的技巧来水平工作,无论如何,进度面板的首选水平尺寸是不一定对。一种几乎可行的方法是在进度面板周围使用带有水平和垂直支柱的 BorderLayout,但进度面板的大小仍然不正确,并且在调整主面板大小时需要更改支柱。

那你会怎么做?

  • 在主面板中使用不同的布局管理器?
  • 以某种方式使用 LayeredPane 或 OverlayLayout?
  • 向包含图像面板和进度面板的包含层次结构添加更多层?
  • 以上的某种组合,还是其他?

如何调整文本大小。调整面板大小时是否需要显式创建新字体,或者有什么方法可以更自动地执行此操作? -

【问题讨论】:

  • 恕我直言,在调整窗口中的控件大小时缩放字体大小并不常见。并不是说这一定是一个坏主意,但这绝对不会融入 Swing。不过,鉴于显示尺寸的多样性,我确实很欣赏允许在现代浏览器中更改文本大小的 UI。所以它可能是一个单独的功能,你可以在这部分之后使用:CTRL +/- to change font size.

标签: java swing jpanel font-size layout-manager


【解决方案1】:

JProgressBar 的首选大小由 UI 委托 BasicProgressBarUI 指定。下面的示例说明了各种布局管理器的效果。 FlowLayout 仅使用UIManager 默认值ProgressBar.horizontalSize,而GridLayoutBorderLayout.CENTER 填充可用空间。 BoxLayout,带有侧翼胶,随着框架大小的调整而按比例调整。

我已经在使用SwingWorker

SwingWorkerprocess() 方法更新GUI 应该是安全的。您可以更改图层甚至删除组件,但我会警惕任何过于复杂的事情。

附录:这是相关的默认值。

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();
            }
        });
    }
}

【讨论】:

    【解决方案2】:

    我知道这是一个布局问题,但如果您有有用的临时结果,SwingWorker 可能会使问题变得更简单。我有时会从这个example开始。

    【讨论】:

    • 谢谢。我已经在使用SwingWorker 来计算图像并设置进度条的值。在某些时候,我希望在创建不完整的图像时对其进行渲染。这只是我用来提高我对 Swing 知识的一个玩具项目。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-18
    • 1970-01-01
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    • 2016-02-21
    相关资源
    最近更新 更多