如何在JPanel上叠加,调整大小并使组件居中? [英] How to overlay, resize and centre a component on a JPanel?

查看:175
本文介绍了如何在JPanel上叠加,调整大小并使组件居中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've spent a while reading and experimenting here, and come up with a few approaches, but not got any of them to work completely yet, so I would like to know what more experienced Swing programmers would do.

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

The main window of my application contains a custom subtype of JPanel, which is used to display an image calculated from a mathematical function. This can take some time to calculate, so while this happens I display a text message and a progress bar superimposed on the middle of the panel. I would like both the text and the progress bar to resize appropriately when the panel is resized, probably using a constant fraction of the width of the panel.

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

At the moment I have another JPanel subtype that contains the text and the progress bar, and I add this "progress panel" to the main panel, and set it to be visible when required. The main panel does not contain any other components, but has its own paintComponent() method to display a BufferedImage obtained from another class. There are a few problems with this as it stands:

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

那你会怎么做?

  • 在主面板中使用其他布局管理器吗?
  • 以某种方式使用LayeredPane或OverlayLayout?
  • 要在包含图像面板和进度面板的容纳层次结构中再添加一层?
  • 上述内容的组合还是其他?

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

What about resizing the text. Do I need to explicitly create a new Font when the panel is resized, or is there any way to do this more automatically? -

推荐答案

The preferred size of JProgressBar is specified by the UI delegate, BasicProgressBarUI. The example below illustrates the effect of various layout managers. FlowLayout simply uses the UIManager default, ProgressBar.horizontalSize, while GridLayout and BorderLayout.CENTER fill the available space. BoxLayout, with flanking glue, adjusts proportionally as the frame is resized.

我已经在使用SwingWorker

SwingWorkerprocess()方法更新GUI应该是安全的.您可以更改图层甚至删除组件,但是对于任何过于复杂的内容,我都会保持警惕.

Updating the GUI from the process() method of your SwingWorker should be safe. You can change layers or even remove components, but I'd be wary of anything overly complicated.

附录:这是相关的默认设置.

Addendum: Here's the relevant default.

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

这篇关于如何在JPanel上叠加,调整大小并使组件居中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆