我创建了一个扩展JButton的自定义按钮类。当我将其添加到JFrame时,我得到了这个:
但是当我使用BoxLayout将此自定义按钮放入框架时,按钮会变小并且不希望这样:
这是我的框架代码:
Test.java
import javax.swing.BoxLayout;
import javax.swing.JFrame;
public class Test {
public static void main(String[] args) {
JFrame frame = new JFrame();
//When you uncomment this, the button is sized really small
//frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(),BoxLayout.PAGE_AXIS));
frame.add(new CButton("Hello"));
frame.pack();
frame.setVisible(true);
}
}
这是自定义按钮的代码,CButton:
CButton.java
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JToolTip;
public class CButton extends JButton implements ComponentListener {
protected static final int BORDER_WIDTH = 5;
private static final Insets INSETS_MARGIN = new Insets(2, 5, 2, 5);
private static final long serialVersionUID = 1L;
protected Area m_areaDraw = null;
private Area m_areaFill = null;
private double m_dHeightDraw = 0d;
private double m_dHeightFill = 0d;
private double m_dWidthDraw = 0d;
private double m_dWidthFill = 0d;
private int m_nMinHeight = 0;
private int m_nMinWidth = 0;
private int m_nStringHeightMax = 0;
private int m_nStringWidthMax = 0;
private RoundRectangle2D m_rrect2dDraw = null;
private RoundRectangle2D m_rrect2dFill = null;
private Shape m_shape = null;
public CButton(String strLabel) {
setContentAreaFilled(false);
setMargin(INSETS_MARGIN);
setFocusPainted(false);
addComponentListener(this);
setText(strLabel);
}
@Override
public void componentHidden(ComponentEvent e) {
}
@Override
public void componentMoved(ComponentEvent e) {
}
// Needed if we want this button to resize
@Override
public void componentResized(ComponentEvent e) {
m_shape = new Rectangle2D.Float(0, 0, getBounds().width,
getBounds().height);
m_dWidthFill = (double) getBounds().width - 1;
m_dHeightFill = (double) getBounds().height - 1;
m_dWidthDraw = ((double) getBounds().width - 1)
- (CButton.BORDER_WIDTH - 1);
m_dHeightDraw = ((double) getBounds().height - 1)
- (CButton.BORDER_WIDTH - 1);
setShape();
repaint();
}
@Override
public void componentShown(ComponentEvent e) {
}
@Override
public boolean contains(int nX, int nY) {
if ((null == m_shape) || m_shape.getBounds().equals(getBounds())) {
m_shape = new Rectangle2D.Float(0, 0, this.getBounds().width,
this.getBounds().height);
}
return m_shape.contains(nX, nY);
}
@Override
public void paintBorder(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
RenderingHints hints = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHints(hints);
g2.setColor(Color.black);
Stroke strokeOld = g2.getStroke();
g2.setStroke(new BasicStroke(CButton.BORDER_WIDTH,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
if (getModel().isRollover()) {
g2.setColor(Color.ORANGE);
}
if (!getModel().isEnabled()) {
g2.setColor(Color.GRAY);
}
g2.draw(m_areaDraw);
g2.setStroke(strokeOld);
};
@Override
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
RenderingHints hints = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHints(hints);
if (getModel().isArmed()) {
g2.setColor(Color.CYAN.darker());
} else {
g2.setColor(Color.CYAN);
}
g2.fill(m_areaFill);
super.paintComponent(g2);
}
private void setShape() {
// Area
double dArcLengthFill = Math.min(m_dWidthFill, m_dHeightFill);
m_rrect2dFill = new RoundRectangle2D.Double(0d, 0d, m_dWidthFill,
m_dHeightFill, dArcLengthFill, dArcLengthFill);
// WARNING: arclength and archeight are divided by 2
// when they get into the roundedrectangle shape
m_areaFill = new Area(m_rrect2dFill);
// Border
double dArcLengthDraw = Math.min(m_dWidthDraw, m_dHeightDraw);
m_rrect2dDraw = new RoundRectangle2D.Double(
(CButton.BORDER_WIDTH - 1) / 2, (CButton.BORDER_WIDTH - 1) / 2,
m_dWidthDraw, m_dHeightDraw, dArcLengthDraw, dArcLengthDraw);
m_areaDraw = new Area(m_rrect2dDraw);
}
@Override
public void setText(final String strText) {
super.setText(strText);
Frame frame = JOptionPane.getRootFrame();
FontMetrics fm = frame.getFontMetrics(getFont());
m_nStringWidthMax = fm.stringWidth(getText());
m_nStringWidthMax = Math.max(m_nStringWidthMax,
fm.stringWidth(getText()));
// WARNING: use getMargin. it refers to dist btwn text and border.
// Also use getInsets. it refers to the width of the border
int nWidth = Math.max(m_nMinWidth, m_nStringWidthMax + getMargin().left
+ getInsets().left + getMargin().right + getInsets().right);
m_nStringHeightMax = fm.getHeight();
// WARNING: use getMargin. it refers to dist btwn text and border.
// Also use getInsets. it refers to the width of the border
int nHeight = Math.max(m_nMinHeight, m_nStringHeightMax
+ getMargin().left + getInsets().left + getMargin().right
+ getInsets().right);
setPreferredSize(new Dimension(
nWidth + ((2 * getFont().getSize()) / 5), nHeight
+ ((2 * getFont().getSize()) / 5)));
// Set the initial draw and fill dimensions
setShape();
}
}
有没有办法可以解决这个问题并使其达到最大尺寸?
答案 0 :(得分:1)
覆盖getPreferredSize()
。 BoxLayout尊重首选尺寸。如果您没有,首选大小将由文本决定。它在框架中更大,因为框架的默认BorderLayout不会考虑首选大小,并会拉伸按钮。你可以做的另一件事是设置更大的边距和/或更大的字体,因为这也会增加首选尺寸。所以你有几个选择/事情需要考虑
看看here哪个布局符合首选尺寸,哪些不适合。另一个总是很好的资源是Laying out Components Within a Container