gpt4 book ai didi

java - Java Swing 中具有设置像素高度的项目的可滚动列表

转载 作者:行者123 更新时间:2023-11-30 06:56:57 25 4
gpt4 key购买 nike

我正在尝试在 swing 中创建一个 GUI。 GUI 将容纳可变数量的固定高度的 JPanel,它们相互堆叠。当堆栈中 JPanel 的总高度大于封闭框架的高度时,用户应该能够在面板中上下滚动。

         ____________________
| |
| panel 1 |
| |
|____________________|
| |
| panel 2 |
| |
|____________________|
___|____________________|___
| | panel 3 | |
| | | |
| |____________________| | ^
| | | | |
| | panel 4 | | |
| | | | |
| |____________________| | v
| | | |
| | panel 5 | |
|___|____________________|___|
|____________________|
| |
| panel 6 |
| |
|____________________|

我尝试将 JScrollPaneJPanelGridLayoutGridBagLayout 结合使用因为对 setPreferedSizesetMinimumSize 的调用没有成功。我觉得设置这种 gui 应该相当简单,但似乎无法找到解决方案。

最佳答案

如果您使用 JPanels,那么由视口(viewport)持有的 JPanel 应该覆盖 JPanel 类并且应该实现 Scrollable 接口(interface),为覆盖的方法返回正确的值,尤其是 getPreferredScrollableViewportSize() 方法.不过,为了我的钱,我更愿意使用 JList 并使用适当的渲染器而不是 JPanel,然后通过其 setVisibleRowCount(...) 方法设置我的 JLists visibleRowCount。

例如:

示例编辑为现在同时显示 JList 和 Scrollable JPanel

import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import javax.swing.*;

@SuppressWarnings("serial")
public class VisibleRows extends JPanel {
private DefaultListModel<Datum> dataModel = new DefaultListModel<>();
private JList<Datum> datumList = new JList<>(dataModel);

public VisibleRows() {
DataPanel dataPanel = new DataPanel(8);
for (int i = 0; i < 200; i++) {
String name = "John Smith " + i;
int value = i;
Datum datum = new Datum(name, value);
dataPanel.addDatum(datum);
dataModel.addElement(datum);
}

JScrollPane scrollPane1 = new JScrollPane(dataPanel);
scrollPane1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

add(scrollPane1);

datumList.setVisibleRowCount(8);
datumList.setCellRenderer(new DatumRenderer());
datumList.setPrototypeCellValue(new Datum("XXXXXXXXXXX", 200));
JScrollPane scrollPane2 = new JScrollPane(datumList);
scrollPane2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

add(scrollPane2);

}

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

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

@SuppressWarnings("serial")
class DatumRenderer extends DatumPanel implements ListCellRenderer<Datum> {

@Override
public Component getListCellRendererComponent(JList<? extends Datum> list, Datum value, int index,
boolean isSelected, boolean cellHasFocus) {
setDatum(value);
return this;
}

}

@SuppressWarnings("serial")
class DataPanel extends JPanel implements Scrollable {
private int visibleRowCount = 1;

public DataPanel(int visibleRowCount) {
this.visibleRowCount = visibleRowCount;
setLayout(new GridLayout(0, 1));
}

public void addDatum(Datum datum) {
add(new DatumPanel(datum));
}

@Override
public Dimension getPreferredScrollableViewportSize() {
if (getComponentCount() > 0) {
JComponent comp = (JComponent) getComponents()[0];
int width = getPreferredSize().width;
int height = visibleRowCount * comp.getPreferredSize().height;
Dimension d = new Dimension(width, height);
System.out.println(d);
return d;
} else {
return new Dimension(0, 0);
}
}

@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
if (getComponentCount() > 0) {
JComponent comp = (JComponent) getComponents()[0];
Dimension d = comp.getPreferredSize();
if (orientation == SwingConstants.VERTICAL) {
return d.height;
} else {
return d.width;
}
}
return 0;
}

@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
if (getComponentCount() > 0) {
JComponent comp = (JComponent) getComponents()[0];
Dimension d = comp.getPreferredSize();
if (orientation == SwingConstants.VERTICAL) {
return visibleRowCount * d.height;
} else {
return d.width;
}
}
return 0;
}

@Override
public boolean getScrollableTracksViewportWidth() {
return true;
}

@Override
public boolean getScrollableTracksViewportHeight() {
return false;
}

}

@SuppressWarnings("serial")
class DatumPanel extends JPanel {
private static final int GBC_I = 3;
private Datum datum;
private JLabel nameLabel = new JLabel();
private JLabel valueLabel = new JLabel();

public DatumPanel() {
setLayout(new GridBagLayout());
add(new JLabel("Name:"), createGbc(0, 0));
add(nameLabel, createGbc(1, 0));
add(new JLabel("Value:"), createGbc(0, 1));
add(valueLabel, createGbc(1, 1));
}

public DatumPanel(Datum datum) {
this();
setDatum(datum);
}

public final void setDatum(Datum datum) {
this.datum = datum;
nameLabel.setText(datum.getName());
valueLabel.setText("" + datum.getValue());
}

public Datum getDatum() {
return datum;
}

private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.insets = new Insets(GBC_I, GBC_I, GBC_I, GBC_I);
gbc.insets.left = x != 0 ? 3 * GBC_I : GBC_I;
gbc.weightx = 0.0;
gbc.weighty = 0.0;
return gbc;
}
}

class Datum {
private String name;
private int value;

public Datum(String name, int value) {
this.name = name;
this.value = value;
}

public String getName() {
return name;
}

public int getValue() {
return value;
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Name: " + name + "\n");
sb.append("Value: " + value);
return super.toString();
}

}

关于java - Java Swing 中具有设置像素高度的项目的可滚动列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33894580/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com