我正在尝试使用Java Swing为小型电话本应用程序编写布局.我遇到了一个我无法修复的大小问题.我希望过滤器(在搜索结果下显示)足够宽,以便在搜索短语很短时显示整个标题.这是它的样子:
如你所见,名字缩短了.姓氏带有更长的文本,并按我的要求显示.
过滤类:
import javax.swing.*;
import javax.swing.border.CompoundBorder;
import java.awt.*;
public class Filter
{
private JLabel label;
private JPanel filterPane;
Filter(String name)
{
// Filter text
label = new JLabel();
label.setForeground(new Color(0xAA0000));
// Closing button
JButton closeButton = new JButton("X");
closeButton.setFont(new Font("Dialog", Font.BOLD, 20));
closeButton.setMargin(new Insets(0, 0, 0, 0));
filterPane = new JPanel();
filterPane.setLayout(new BoxLayout(filterPane, BoxLayout.X_AXIS));
// Frame with title + 50px padding on the right side for the next filter
filterPane.setBorder(new CompoundBorder(
BorderFactory.createEmptyBorder(0, 0, 0, 50),
BorderFactory.createTitledBorder(name)));
filterPane.add(closeButton);
filterPane.add(Box.createRigidArea(new Dimension(5, 0)));
filterPane.add(label);
filterPane.setVisible(false);
}
public void setValue(String value) {
if (value == null || value.isEmpty())
filterPane.setVisible(false);
else
{
this.label.setText(value);
filterPane.setVisible(true);
}
}
public JPanel getFilterPane() {
return filterPane;
}
}
Run Code Online (Sandbox Code Playgroud)
主要课程:
import javax.swing.*;
import java.awt.*;
import java.lang.reflect.InvocationTargetException;
public class TestWindow
{
private static void init()
{
JFrame frame = new JFrame("Stackoverflow test window");
frame.setSize(new Dimension(480, 320));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
// Main panel - 20 px padding from each side
JPanel pane = new JPanel();
pane.setLayout(new BorderLayout());
pane.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
// Create panel for filters
JPanel filterPane = new JPanel();
filterPane.setLayout(new BoxLayout(filterPane, BoxLayout.X_AXIS));
filterPane.setPreferredSize(new Dimension(0, 60));
// Add sample filters
Filter filter = new Filter("name");
filter.setValue("i");
filter.getFilterPane().setAlignmentY(Component.BOTTOM_ALIGNMENT);
filterPane.add(filter.getFilterPane());
filter = new Filter("surname");
filter.setValue("loooooong text");
filter.getFilterPane().setAlignmentY(Component.BOTTOM_ALIGNMENT);
filterPane.add(filter.getFilterPane());
// Add everything to main panel
pane.add(new JTextArea("Nothing fancy here, just to fill out space"), BorderLayout.CENTER);
pane.add(filterPane, BorderLayout.SOUTH);
frame.setContentPane(pane);
frame.setVisible(true);
}
public static void main (String [] args) throws InterruptedException, InvocationTargetException {
SwingUtilities.invokeLater(TestWindow::init);
}
}
Run Code Online (Sandbox Code Playgroud)
我想setMinimumSize和setPreferredSize两个label并filterPane在过滤器的构造,但它并没有帮助.请问你能帮帮我吗?
这个问题实际上是由两个问题组成的.
TitledBorder,组件在计算其首选大小时不会考虑标题的大小.BoxLayout,除非在组件后面添加"水平胶水",否则将忽略首选宽度.因此,要解决第一个问题,您需要覆盖getPreferredSize()JPanel 的方法.但要实现这一点,您还需要通过添加胶水来绕过第二个问题.
要覆盖getPreferredSize(),您可以使用以下内容:
class MinSizePanel extends JPanel {
public Dimension getPreferredSize() {
Dimension original = super.getPreferredSize();
TitledBorder titleBorder = (TitledBorder)((CompoundBorder)getBorder()).getInsideBorder();
int width = (int)Math.max( original.getWidth(), 60 + (int)titleBorder.getMinimumSize(this).getWidth());
return new Dimension( width, (int)original.getHeight() );
}
}
Run Code Online (Sandbox Code Playgroud)
这得到了TitledBorder来自CompoundBorder,得到它的最小尺寸(这是一个考虑标题宽度的方法),为空边框和插图添加一些额外的(你可以添加适当的计算,我做了一个快捷方式,只是使用60.. .),并使用它(如果它超过组件的宽度).
代替
filterPane = new JPanel();
Run Code Online (Sandbox Code Playgroud)
使用
filterPane = new MinSizePanel();
Run Code Online (Sandbox Code Playgroud)
(您应该将面板构造的所有其余部分移动到该类中).
在TestWindow课堂上,在最后一课之后
filterPane.add(filter.getFilterPane());
Run Code Online (Sandbox Code Playgroud)
还添加
filterPane.add(Box.createHorizontalGlue());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1188 次 |
| 最近记录: |