How to overlay, resize and center a component on JPanel?

I spent some time reading and experimenting here, and came up with several approaches, but didn't get any of them to work completely, so I would like to know what more experienced Swing programmers will do.

The main window of my application contains a custom subtype of JPanel, which is used to display an image calculated from a mathematical function. It may take some time to calculate, so while this is happening, I display a text message and a progress bar superimposed in the middle of the panel. I would like the text and progress bar to change accordingly when the panel is resized, possibly using a constant fraction of the panel width.

At the moment, I have another subtype of JPanel that contains text and a progress bar, and I add this “progress bar” to the main panel and install it when necessary. The main panel does not contain any other components, but has its own paintComponent () method for displaying a BufferedImage obtained from another class. There are several problems with this:

  • The progress bar is not always visible when it should be, perhaps because there is no anywhere in the code that explicitly guarantees that it will be painted before the image.
  • The progress bar always takes up the full width of the application bar. It is centered vertically using BoxLayout on the main panel with some vertical glue before and after the progress panel, but I was not able to get the same trick to work horizontally, and in any case, the preferred horizontal size of the progress panel is not necessarily correct. One approach that almost works is to use a BorderLayout with horizontal and vertical braces around the progress bar, but the size of the progress bar is still wrong, and the racks must be resized when the main panel is resized.

So what would you do?

  • Use a different layout manager on the main panel?
  • Use LayeredPane or OverlayLayout in some way?
  • Add an extra layer to the containment hierarchy containing the image panel and the progress panel?
  • Some combination above, or something else?

How to resize text. Do I need to explicitly create a new font when resizing the panel, or is there a way to do this more automatically? -

+6
source share
2 answers

The preferred JProgressBar size JProgressBar specified by the user interface delegate, BasicProgressBarUI . The example below illustrates the impact of various layout managers. FlowLayout simply uses the default UIManager , ProgressBar.horizontalSize , and GridLayout and BorderLayout.CENTER fill the available space. BoxLayout , with flanking adhesive, changes proportionally when the frame is resized.

I already use SwingWorker

Updating the GUI from the process() method of your SwingWorker should be safe. You can change layers or even remove components, but I would be afraid of something too complicated.

Preogress test

Addendum: Here is the corresponding default.

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

the code:

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

I know this is a layout issue, but SwingWorker can make the problem easier if you have useful intermediate results. I sometimes start with this.

+2
source

Source: https://habr.com/ru/post/896317/


All Articles