- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
昨天我在向 JScrollPane 添加
。 JTable
和 JPanel
(其中包含 JButton
)时出错JButton
固定在表格的底部,单击时它会向 JTable
添加一行。
问题是如果表格变得比 JScrollPane
大,它只会让你滚动到 JTable
的底部;您无法再访问 JButton
。今天,我制作了一个 MCVE 来尝试获得帮助,但首先我对它进行了更多的尝试并最终解决了我的问题,但是在某种程度上给我留下的问题多于答案......这是我准备的 MCVE:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
public class MCVE extends JFrame{
private JButton addRow;
private MCVEModel tableModel;
private JTable table;
private JScrollPane pane;
private JPanel scrollPanel, panel;
public static void main (String[] args) {
new MCVE();
}
public MCVE() {
initialize();
}
public void initialize () {
this.setTitle("Halp");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setBounds(50, 50, 500, 300);
this.setResizable(false);
JPanel mainPanel = new JPanel(new GridBagLayout());
/** The JPanel everything is put into **/
scrollPanel = new JPanel();
scrollPanel.setLayout(new BoxLayout(scrollPanel, BoxLayout.Y_AXIS));
/** The JScrollPane we're using **/
pane = new JScrollPane(scrollPanel);
pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
pane.getVerticalScrollBar().setUnitIncrement(10);
/** The button which keeps getting cut off.... **/
addRow = new JButton("...");
addRow.setBackground(Color.WHITE);
addRow.setMnemonic('R');
addRow.setFocusable(false);
addRow.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
addNewRow();
}
});
/** I wrap the button into this panel so I can affix it to the left **/
panel = new JPanel();
panel.setMinimumSize(new Dimension(0, 20));
panel.setLayout(null);
addRow.setBounds(0, 0, 35, 15);
panel.add(addRow);
/** Faking some data to get the table to populate **/
ArrayList<List<String>> allData = new ArrayList<List<String>>();
ArrayList<String> fakeData = new ArrayList<String>();
fakeData.addAll(Arrays.asList(
new String[]{"this", "is", "just", "sample", "data"}));
for(int i = 0; i < 5; i++)
allData.add(fakeData);
List<String> columnNames = Arrays.asList(new String[] {"", "", "", "", ""});
tableModel = new MCVEModel(columnNames, allData);
table = new JTable();
table.setModel(tableModel);
/** Adding it all together **/
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 1;
scrollPanel.add(table);
scrollPanel.add(panel);
mainPanel.add(pane, c);
this.add(mainPanel);
this.setVisible(true);
}
public void addNewRow () {
tableModel.addRow(tableModel.getRowCount(),
new String[]{"true", "", "", "false", "false"});
tableModel.fireTableRowsInserted(
tableModel.getRowCount(), tableModel.getRowCount());
}
}
/**
* Just here to keep things compilable. Seriously cut back for the MCVE,
* but still replicates the problem without any errors.
* Nothing below here should be relevant to the issue.
*/
class MCVEModel extends DefaultTableModel {
private static final long serialVersionUID = -6598574844380686148L;
private List<String> columnNames;
private List<List<String>> values;
public MCVEModel (List<String> columnNames, List<List<String>> strings) {
this.columnNames = columnNames;
this.values = strings;
}
public int getColumnCount() {
return columnNames.size();
}
public int getRowCount() {
return values == null || values.size() == 0 ? 0 : values.get(0).size();
}
public String getColumnName(int col) {
return columnNames.get(col);
}
public Object getValueAt(int row, int col) {
return values.get(col).get(row);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public Class getColumnClass(int c) {
return String.class;
}
public boolean isCellEditable(int row, int col) {
return true;
}
public void setValueAt(Object value, int row, int col) {
values.get(col).set(row, (String) value);
fireTableCellUpdated(row, col);
}
public void removeRow(int row) {
for(int i = 0; i < values.size(); i++)
values.get(i).remove(row);
this.fireTableRowsDeleted(row, row);
}
public void addRow(int row, String[] strings) {
for(int i = 0; i < values.size(); i++)
values.get(i).add(row, strings[i]);
fireTableRowsInserted(row, row);
}
}
问题出在这一行:
panel.setMinimumSize(new Dimension(0, 20));
更准确的说,是“最小”二字。通过将其更改为:
panel.setPreferredSize(new Dimension(0, 20));
我得到了我需要的功能。现在,当表格对于 JScrollPanel
来说太大时,我们仍然可以向下滚动并看到 JButton
;它不再被切断。
我假设这意味着 JPanel
的父级不遵守其最小尺寸,但它确实遵守其首选尺寸。为什么是这样?我原以为 setPreferredSize()
、setMinimumSize()
和 setMaximumSize()
的交互就像是“我宁愿这么大,但是无论如何我都不能小于我的最小值或大于我的最大值,”但似乎并非如此。我知道这些方法都不应该过于频繁地使用,但是我什么时候应该使用 setMinimumSize()
而不是 setPreferredSize()
,反之亦然?
最佳答案
神奇的是这一行:
scrollPanel.add(panel);
因此,scrollPanel
将包含此面板。然后,JScrollPane
遵循 preferredSize
-s。这是有道理的,因为它的目的是通过使用滚动条为包含的组件腾出足够的空间。换句话说,JScrollPane
-s 实现忽略了 minimumSize
-s。
更新:
从另一个角度来看,JScrollPane
-s 源代码会检查其子项的preferredSize
,但不会检查minimumSize
。这里没什么深意,JScrollPane
就是这么实现的。
关于java - 为什么 setPreferredSize() 有时会优先于 setMinimumSize()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38875753/
这是我第一次尝试使用 Java,所以请放轻松。我查看了其他 JFrame 问题,但我一直无法找到可行的解决方案。 出于某种原因,我无法使 setPreferredSize 或 setSize 工作。
为什么 p1.setPreferredSize(new Dimension(200,200)) 显示错误。它说非法开始类型 class Menu extends JFrame { JPane
我有一个包含多个面板的窗口。我无权访问窗口代码。 (我只能修改面板的代码。) 我从面板中删除了几个组件。窗口已缩小其大小。但是窗口太小,无法正确显示所有内容。 我添加了行 setPreferredSi
代码: import java.awt.Dimension; import javax.swing.*; public class Game extends JFrame { private
我正在尝试正确调整 JPanel 的大小,使其完全适合渲染的 8 x 8 棋盘。当我使用绘画程序放大时,我注意到宽度和高度上都添加了两个额外的像素...... 这还不错,但是当我用其他 JPanel(
我最初使用的是 setSize,但由于 java 边框和标题空间,这导致屏幕内容略大于屏幕。所以我使用了 setpreferredSize,现在屏幕尺寸有点太大了。在我的内容的右侧和底部留一个空格。
根据以前的经验,每个人都会说“不要使用那些 setXxxSize 方法!使用布局管理器!”但是,在这种情况下我该怎么办? import java.awt.*; import javax.swing.*
代码如下: import javax.swing.*; import java.awt.event.*; import java.awt.*; public class TestGrid {
我正在用 Java 创建一个 Tic Tac Toe 游戏,我似乎陷入了一个我无法摆脱的问题:(。我无法调整我的按钮大小。我尝试了 setSize 和 setPreferredSize,但似乎不起作用
根据我收到的答案,我现在采用不同的方式进行此操作。 是否有任何方法可以重写 setPreferredSize() 和 getPreferredSize() ,以便它实际上将组件的大小设置为高于实际输入
我正在尝试构建自己的 JComponent,但一开始并不理想。我可以创建一个对象,然后将其添加到 JFrame 或 JPanel,它将添加到组件列表中。我不知道如何设置PreferredSize()。
在布局管理器中,当我使用 setPreferedSize 时,它增加了 JLabel 的大小,但在之后仅显示一个单词,例如 (JLabel = Name)使用setPreferedSize JLabe
我正在使用 JScrollPane 并在 viewportView.doLayout 内调用 viewportView.setPreferredSize。但这似乎是错误的,因为 JScrollPane
昨天我在向 JScrollPane 添加 JTable 和 JPanel(其中包含 JButton)时出错。 JButton 固定在表格的底部,单击时它会向 JTable 添加一行。 问题是如果表格变
我已经使用 View 过滤方法成功过滤了一个 JTree(在树渲染中,将首选组件大小设置为 0 以过滤掉项目)。请参阅 [ Filtering on a JTree 我有一个包含超过 100 万个树项
我在这里读了一些帖子,我开始了解为什么有些人会这样做 @Override public Dimension getPreferredSize() { return new Dimension(
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我想要一个串联的 JPanel 的“列表”,其中每个单元格都有相应的 JPanel 的大小。例如: 在此示例中,Panel1 的 setPreferredSize 小于 Panel2 的 setPre
所以我一直在尝试为牙医创建这个简单的用户界面,当我在标题下添加顶部菜单时,我注意到“setPreferredSize”没有按预期工作。基本上我希望菜单水平扩展,所以我使用 GridBagLayout
我有一个 JPanel (imagePanel),可以在其上显示图像。我在另一个 JPanel (scrollPanel) 中有 imagePanel,并使用 GridBagLayout 默认约束将其
我是一名优秀的程序员,十分优秀!