簡體   English   中英

JPanel中行的動態寬度和固定高度

[英]Dynamic width and fixed height of rows in JPanel

我正在嘗試使用Java布局管理器(我沒有外部庫,並且正在使用Java 7)創建一種布局,其中數據以行的形式提供,其中行具有固定的高度,但寬度可以填充以適合窗口。 下面提供了一個示例:

布局示例

我的想法是,我將在應用程序的整個運行過程中添加行,並且每行都將被簡單地添加到底部列表中。 如果窗口中添加了太多行,則會出現一個滾動條(我已對該行進行了排序)。

到目前為止,我的問題是,如果對主JPanel使用GridLayout,它將使行填充到整個窗口中,並隨着添加更多行而使每行變小。 我想要這樣,無論添加多少行,行的高度始終保持不變。

每行由兩列組成,其寬度應相同。 因此,為此,我認為GridLayout可以很好地工作,但是我認為我需要將GridLayout添加到實質上代表整個行的另一個面板中。

最好使用Swing布局管理器來實現所需的布局,但是如果提出了其他建議,那么我一定會對其進行研究。 正如我看到的許多其他問題中發現的那樣,許多人似乎都發現Java的布局管理器似乎在某些領域有所欠缺,不幸的是,我無法確定何時缺少我的知識,而不是語言本身。

我的第一個建議是使用JTable ,盡管它似乎“看起來”很復雜,但該API已經過優化,非常高效,可以處理數千行

如果那不能滿足您的需求,那么如果您不想使用任何第三方庫,我會考慮使用GridBagLayout ,訣竅是知道如何操縱它們以實現所需的結果,例如,以下用法三個面板,主要的“外部”面板(充當主視圖)和兩個內部面板。 一個用來容納內容,另一個用來充當填充物,因此內容總是被推到視圖的頂部。

布局

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.Scrollable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                TestPane tp = new TestPane();
                JButton add = new JButton("Add Row");
                add.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        tp.addRow();
                    }
                });

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JScrollPane(tp));
                frame.add(add, BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel implements Scrollable {

        private JPanel content;
        private JPanel filler;

        private GridBagConstraints masterConstraints;

        public TestPane() {

            content = new JPanel(new GridBagLayout());
            filler = new JPanel();

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.weightx = 1;
            gbc.fill = GridBagConstraints.HORIZONTAL;

            add(content, gbc);
            gbc.weighty = 1;
            add(filler, gbc);

            masterConstraints = new GridBagConstraints();
            masterConstraints.gridwidth = GridBagConstraints.REMAINDER;
            masterConstraints.weightx = 1;
            masterConstraints.fill = GridBagConstraints.HORIZONTAL;
        }

        public void addRow() {
            JLabel label = new JLabel("This is just a label, but technically, you can anythig you want");
            content.add(label, masterConstraints);
            revalidate();
            repaint();
        }

        @Override
        public Dimension getPreferredScrollableViewportSize() {
            return new Dimension(200, 200);
        }

        @Override
        public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 64;
        }

        @Override
        public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 64;
        }

        @Override
        public boolean getScrollableTracksViewportWidth() {
            Container parent = getParent();
            boolean trackWidth = false;
            if (parent instanceof JViewport) {
                trackWidth = parent.getHeight() > getPreferredSize().width;
            }
            return trackWidth;
        }

        @Override
        public boolean getScrollableTracksViewportHeight() {
            Container parent = getParent();
            boolean trackHeight = false;
            if (parent instanceof JViewport) {
                trackHeight = parent.getHeight() > getPreferredSize().height;
            }
            return trackHeight;
        }

    }

}

看看如何使用GridBagLayout了解更多詳細信息

“但是,難道沒有更簡單的方法嗎?” 我聽到你在問! 好吧,您可以使用SwingLabs SwingX庫 (或JTable )中的VerticalLayout

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM