我正在研究一个看起来像这样的下载器:

Screenshot

Jframe使用BorderLayout。在北部,我有一个jpanel(Flowlayout)。在南部,还有一个jpanel(Flowlayout),在西部,我只有一个Jtextarea(在Jscrollpane中)。这一切都正确显示。但是,在东部,我目前有一个Jpanel(Gridlayout(10,1))。

我想在东部部分出现10个Jprogressbars,并动态从面板中添加并删除。问题是,我无法让它们看起来像我要看它们:我想要Jprogressbars的宽度以填充整个东部部分,因为1)这使应用程序更具对称性外观,2)Progressbars可能包含目前不适合的长弦。我已经尝试将包含Gridlayout(10,1)的JPanel放入Flowlayout中,然后将Flowlayout放在东部部分,但这也不起作用。

我的代码(SSCCE)当前如下:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;

public class Main {

    public static void main(String[] args) {
        new DownloadFrame();
    }

    private static class DownloadFrame extends JFrame {

        private JButton downloadButton;
        private JTextField threadIdTextField;
        private JTextArea downloadStatusTextArea;
        private JScrollPane scrollPane;
        private JTextField downloadLocationTextField;
        private JButton downloadLocationButton;

        private JPanel North;
        private JPanel South;
        private JPanel ProgressBarPanel;

        private Map<String, JProgressBar> progressBarMap;

        public DownloadFrame() {
            InitComponents();
            InitLayout();
            AddComponents();
            AddActionListeners();

            setVisible(true);
            setSize(700, 300);
        }

        private void InitComponents() {
            downloadButton = new JButton("Dowload");
            threadIdTextField = new JTextField(6);
            downloadStatusTextArea = new JTextArea(10, 30);
            scrollPane = new JScrollPane(downloadStatusTextArea, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
            downloadLocationTextField = new JTextField(40);
            downloadLocationButton = new JButton("...");
            North = new JPanel();
            South = new JPanel();
            ProgressBarPanel = new JPanel();
            progressBarMap = new HashMap<String, JProgressBar>();
        }

        private void InitLayout() {
            North.setLayout(new FlowLayout());
            South.setLayout(new FlowLayout());
            ProgressBarPanel.setLayout(new GridLayout(10, 1));
        }

        private void AddComponents() {
            North.add(threadIdTextField);
            North.add(downloadButton);
            add(North, BorderLayout.NORTH);

            add(ProgressBarPanel, BorderLayout.EAST);

            South.add(downloadLocationTextField);
            South.add(downloadLocationButton);
            add(South, BorderLayout.SOUTH);

            add(scrollPane, BorderLayout.WEST);
        }

        private void AddActionListeners() {
            downloadButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    addNewProgessBar(threadIdTextField.getText());
                }
            });
        }

        public void addNewProgessBar(String threadId) {
            JProgressBar progressBar = new JProgressBar();
            progressBar.setStringPainted(true);
            progressBarMap.put(threadId, progressBar);
            drawProgessBars();
        }

        void drawProgessBars() {
            ProgressBarPanel.removeAll();
            for (JProgressBar progressBar : progressBarMap.values()) {
                ProgressBarPanel.add(progressBar);
            }
            validate();
            repaint();
        }

    }
}

提前致谢。

编辑

最简单的解决方案:更改

add(ProgressBarPanel, BorderLayout.EAST);

add(ProgressBarPanel, BorderLayout.CENTER);
有帮助吗?

解决方案

Screenshot of GUI

import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;

public class Main {

    public static void main(String[] args) {
        new DownloadFrame();
    }

    private static class DownloadFrame extends JFrame {

        private JButton downloadButton;
        private JTextField threadIdTextField;
        private JTextArea downloadStatusTextArea;
        private JScrollPane scrollPane;
        private JTextField downloadLocationTextField;
        private JButton downloadLocationButton;

        private JPanel North;
        private JPanel South;
        private JPanel ProgressBarPanel;

        private Map<String, JProgressBar> progressBarMap;

        public DownloadFrame() {
            InitComponents();
            AddComponents();
            AddActionListeners();

            pack();
            setVisible(true);
            //setSize(700, 300);
        }

        private void InitComponents() {
            setLayout(new BorderLayout());
            downloadButton = new JButton("Dowload");
            threadIdTextField = new JTextField(6);
            downloadStatusTextArea = new JTextArea(10, 30);
            scrollPane = new JScrollPane(downloadStatusTextArea, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
            downloadLocationTextField = new JTextField(40);
            downloadLocationButton = new JButton("...");
            North = new JPanel(new FlowLayout());
            South = new JPanel(new FlowLayout());
            ProgressBarPanel = new JPanel(new GridLayout(0, 1));
            ProgressBarPanel.setBorder(new LineBorder(Color.black));
            ProgressBarPanel.setPreferredSize(new Dimension(300,20));
            progressBarMap = new HashMap<String, JProgressBar>();
        }

        private void AddComponents() {
            North.add(threadIdTextField);
            North.add(downloadButton);
            add(North, BorderLayout.NORTH);

            add(ProgressBarPanel, BorderLayout.EAST);

            South.add(downloadLocationTextField);
            South.add(downloadLocationButton);
            add(South, BorderLayout.SOUTH);

            add(scrollPane, BorderLayout.WEST);
        }

        private void AddActionListeners() {
            downloadButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    addNewProgessBar(threadIdTextField.getText());
                }
            });
        }

        public void addNewProgessBar(String threadId) {
            JProgressBar progressBar = new JProgressBar();
            progressBar.setStringPainted(true);
            progressBarMap.put(threadId, progressBar);
            drawProgessBars();
        }

        void drawProgessBars() {
            ProgressBarPanel.removeAll();
            for (JProgressBar progressBar : progressBarMap.values()) {
                ProgressBarPanel.add(progressBar);
            }
            validate();
            repaint();
        }

    }
}

其他提示

出色地。可能,但是在你的榜样 CENTER 区域占据了一些 Rectangle, ,很难减少/删除 CENTER 零面积 Size

去北边 JPanel (BorderLayout)另一个 JPanel 并将其放在东方(与 LayoutManager 将会 GridLayout(1,2,10,10))放在这里两个 JComponents JTextField - threadIdTextFieldJButton - downloadButton, ,您需要 setPreferredSize 1) JComponents (正确的方式)或2)整体 JPanel (也可能的方式)

JScrollPaneJTextArea 必须放在 CENTER 区域

JPanelJProgressBars 放置 EAST, ,但再次设置 PreferredSize 至于 JPanelJTextFieldJButton 来自 NORTH

SOUTH JPanel 仍然没有变化

请发布一个可运行的小程序,以提供最快的最佳帮助,一个 SSCCE.

建议包括使用gridlayout(0,1)(可变的行数,一列),或在JLIST中显示Jprogressbars,该JLIST使用使用扩展Jprogressbar的自定义渲染器。

编辑1:
我知道安德鲁(Andrew)已经发布了公认的答案(1+以获得出色的答案),但我只是想证明这可以用Jlist轻松完成,类似的事情:

import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.util.Random;
import javax.swing.*;

public class EastProgressList extends JPanel {
   private DefaultListModel myListModel = new DefaultListModel();
   private JList myList = new JList(myListModel);
   private JTextField downloadUrlField = new JTextField(10);

   public EastProgressList() {
      JButton downLoadBtn = new JButton("Download");
      downLoadBtn.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            downloadAction();
         }
      });
      JPanel northPanel = new JPanel();
      northPanel.add(new JLabel("File to Download:"));
      northPanel.add(downloadUrlField);
      northPanel.add(Box.createHorizontalStrut(15));
      northPanel.add(downLoadBtn);

      myList.setCellRenderer(new ProgressBarCellRenderer());
      JScrollPane eastSPane = new JScrollPane(myList);
      eastSPane.setPreferredSize(new Dimension(200, 100));

      setLayout(new BorderLayout());

      add(new JScrollPane(new JTextArea(20, 30)), BorderLayout.CENTER);
      add(northPanel, BorderLayout.NORTH);
      add(eastSPane, BorderLayout.EAST);
   }

   private void downloadAction() {
      String downloadUrl = downloadUrlField.getText();
      final MyData myData = new MyData(downloadUrl);
      myListModel.addElement(myData);
      myData.addPropertyChangeListener(new PropertyChangeListener() {
         public void propertyChange(PropertyChangeEvent evt) {
            if (evt.getPropertyName().equals(MyData.VALUE)) {
               myList.repaint();
               if (myData.getValue() >= 100) {
                  myListModel.removeElement(myData);
               }
            }
         }

      });
   }

   private class ProgressBarCellRenderer extends JProgressBar implements ListCellRenderer {
      protected ProgressBarCellRenderer() {
         setBorder(BorderFactory.createLineBorder(Color.blue));
      }

      public Component getListCellRendererComponent(JList list, Object value,
               int index, boolean isSelected, boolean cellHasFocus) {
         //setText(value.toString());
         MyData myData = (MyData)value;
         setValue(myData.getValue());
         setString(myData.getText());
         setStringPainted(true);
         return this;
      }
   }

   private static void createAndShowUI() {
      JFrame frame = new JFrame("EastProgressList");
      frame.getContentPane().add(new EastProgressList());
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            createAndShowUI();
         }
      });
   }
}

class MyData {
   public static final int TIMER_DELAY = 300;
   public static final String VALUE = "value";
   protected static final int MAX_DELTA_VALUE = 5;
   private String text;
   private int value = 0;
   private Random random = new Random();
   private PropertyChangeSupport pcSupport = new PropertyChangeSupport(this);

   public MyData(String text) {
      this.text = text;
      new Timer(TIMER_DELAY, new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            int deltaValue = random.nextInt(MAX_DELTA_VALUE);
            int newValue = value + deltaValue;
            if (newValue >= 100) {
               newValue = 100;
               ((Timer)e.getSource()).stop();
            }
            setValue(newValue);
         }
      }).start();
   }

   public String getText() {
      return text;
   }

   public int getValue() {
      return value;
   }

   public void setValue(int value) {
      int oldValue = this.value;
      this.value = value;

      PropertyChangeEvent pcEvent = new PropertyChangeEvent(this, VALUE, oldValue, value);
      pcSupport.firePropertyChange(pcEvent);
   }

   public void addPropertyChangeListener(PropertyChangeListener pcListener) {
      pcSupport.addPropertyChangeListener(pcListener);
   }


}

这会导致GUI看起来像:
enter image description here

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top