如果JFrame调整大小,如何调整JProgressBar的大小

4

我希望在调整JFrame大小时,能够同时调整JProgressBar的大小。

JProgressBar的大小计算方式如下:

progressBar.setPreferredSize(new Dimension(getWidth() - 100, 50));

但是当我调整JFrame的大小时,进度条的大小始终保持不变。
更新1
这是我的代码:
public class MinimalExampleJProgresbar {
    public static void main(String[] args) {
        JFrame frame = new JFrame("SimpleFrame");
        JPanel jPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        JProgressBar progressBar = new JProgressBar();

        jPanel.add(progressBar);
        frame.add(jPanel, BorderLayout.PAGE_START);

        frame.setExtendedState(Frame.MAXIMIZED_BOTH);
        frame.setVisible(true);
        progressBar.setPreferredSize(new Dimension(frame.getWidth() - 100, 50));
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }
}
2个回答

3

善用布局管理器。例如,JFrame 的 contentPane 使用 BorderLayout。如果您将 JProgressBar 添加到此位置的 BorderLayout.PAGE_END 或 BorderLayout.PAGE_END 位置,则在其容器调整大小时,它会自动调整大小。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class SimpleFrame {
   private static void createAndShowGUI() {
      final JProgressBar progressBar = new JProgressBar(0, 100);
      progressBar.setBorder(BorderFactory.createTitledBorder("My Progress"));
      new Timer(200, new ActionListener() {
         int value = 0;

         @Override
         public void actionPerformed(ActionEvent e) {
            value += 10;
            if (value > 100) {
               value = 0;
            }
            progressBar.setValue(value);
         }
      }).start();


      JFrame frame = new JFrame("SimpleFrame");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.add(progressBar, BorderLayout.PAGE_START);
      frame.add(Box.createRigidArea(new Dimension(400, 300)));
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGUI();
         }
      });
   }
}

import java.awt.*;
import javax.swing.*;

public class MinimalExampleJProgresbar2 {
   public static void main(String[] args) {
       JFrame frame = new JFrame("SimpleFrame");
       JPanel wrapperPanel = new JPanel(new BorderLayout());

       JPanel jPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
       JProgressBar progressBar = new JProgressBar();

       wrapperPanel.add(progressBar, BorderLayout.PAGE_START);
       wrapperPanel.add(jPanel, BorderLayout.CENTER);

       frame.add(wrapperPanel, BorderLayout.PAGE_START);

       frame.setExtendedState(Frame.MAXIMIZED_BOTH);
       frame.setVisible(true);
       progressBar.setPreferredSize(new Dimension(frame.getWidth() - 100, 50));
       frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
   }
}

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;    
import javax.swing.*;

public class MinimalExampleJProgresbar2 {
   public static void main(String[] args) {
       JFrame frame = new JFrame("SimpleFrame");
       JPanel wrapperPanel = new JPanel(new BorderLayout());

       JPanel jPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
       final JProgressBar progressBar = new JProgressBar();

       new Timer(200, new ActionListener() {
          int value = 0;

          @Override
          public void actionPerformed(ActionEvent e) {
             value += 10;
             if (value > 100) {
                value = 0;
             }
             progressBar.setValue(value);
          }
       }).start();

       JPanel boxUser = new JPanel();
       boxUser.setLayout(new BoxLayout(boxUser, BoxLayout.LINE_AXIS));
       boxUser.add(Box.createHorizontalStrut(50));
       boxUser.add(progressBar);
       boxUser.add(Box.createHorizontalStrut(50));


       wrapperPanel.add(boxUser, BorderLayout.PAGE_START);
       wrapperPanel.add(jPanel, BorderLayout.CENTER);

       frame.add(wrapperPanel, BorderLayout.PAGE_START);

       frame.setExtendedState(Frame.MAXIMIZED_BOTH);
       frame.setVisible(true);
       frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
   }
}

我的组件被添加到了一个设置为 PAGE_START 的 JPanel 上。JPanel 的布局管理器是 FlowLayout.Left。 - vanlooverenkoen
1
@KoenVanLooveren:不要这样做,不要将其添加到使用FlowLayout的容器中。您可以嵌套使用不同布局的每个JPanel,并以此解决您的问题。如果需要进一步帮助,请创建并发布您的[mcve],类似于我上面发布的代码。 - Hovercraft Full Of Eels
@KoenVanLooveren:我也是 :) - Hovercraft Full Of Eels
好的,我明白了,但在这个例子中我不能设置进度条的高度吗?非常感谢你帮助我。 - vanlooverenkoen
我想暂时将高度设置为50(很大很好看):D,也许将来会调低或调高。 - vanlooverenkoen
显示剩余7条评论

1
在您的框架中添加一个 ComponentAdapter。
myFrame.addComponentListener(new ComponentAdapter() {
  public void componentResized(ComponentEvent ev) {
    progressBar.setPreferredSize(new Dimension(getWidth() - 100, 50));
    revalidate();
    repaint();
  }
});

@KoenVanLooveren:我没有对这个答案进行负面评价,但是当更好的解决方案存在时,它更像是一个临时应急措施。为了得到最佳解决方案,请再次展示您的代码和 [mcve]。 - Hovercraft Full Of Eels
是的,但在您的解决方案中,进度条长度无法按照我想要的方式计算,而使用@ControlAltDel的解决方案则可以实现。 - vanlooverenkoen
使用我的解决方案,进度条长度不需要计算。再次问一句,为什么不创建并发布您的 [mcve] 呢?为什么不让我们一起处理您的代码,找到最优解决方案呢? - Hovercraft Full Of Eels
我仍然认为这是最好的方法,但感谢您的反馈。 - vanlooverenkoen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接