我正在创建一个包含三个JComponents的JPanel:一个宽的自定义JComponent,以及两个自定义的AbstractButtons,它们也从JComponent扩展。
我想组织我的JPanel有2行和2列,宽JComponent跨越两列。 AbstractButtons周围有足够的空间。这是我绘制的我想要实现的图表:
基本上,当用户点击其中一个AbstractButtons时,它会缩小。即使点击它,我也希望它们能够完全集中在细胞中。但是当我使用GridBagLayout时,我的代码中的情况并非如此;按钮变得偏离中心,它们的左上角保持在以前的任何位置。
以下代码会显示(红色按钮现在会在按下后缩小):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class Example
{
public static void main(String[] args)
{
// Instantiate components needed.
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.add(panel);
Button b1 = new Button();
Button b2 = new Button();
WideComponent w = new WideComponent();
// give margins to each component
EmptyBorder padding = new EmptyBorder(20, 20, 20, 20);
b1.setBorder(padding);
b2.setBorder(padding);
w.setBorder(padding);
// Add stuff to panel
panel.add(b1);
panel.add(b2);
panel.add(w);
// Add panel to frame, show frame
frame.add(panel);
frame.setVisible(true);
frame.pack();
}
}
class Button extends AbstractButton implements MouseListener
{
final int WIDTH = 175;
final int HEIGHT = 75;
boolean mousePressed;
public Button()
{
addMouseListener(this);
}
// draw method
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.RED);
if (!mousePressed)
g.fillRect(0, 0, WIDTH, HEIGHT);
else
{
g.fillRect(0, 0, WIDTH - 30, HEIGHT - 30);
g.setColor(Color.YELLOW);
}
}
// MouseListener interface implementation
public void mousePressed(MouseEvent me) { mousePressed = true; repaint(); }
public void mouseReleased(MouseEvent me) { mousePressed = false; repaint(); }
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
// JComponent sizing methods
public Dimension getPreferredSize()
{
return new Dimension(WIDTH, HEIGHT);
}
public Dimension getMaximumSize() { return getPreferredSize(); }
public Dimension getMinimumSize() { return getPreferredSize(); }
}
class WideComponent extends JComponent
{
final int WIDTH = 500;
final int HEIGHT = 150;
// drawing method
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillRect(0, 0, WIDTH, HEIGHT);
}
// JComponent sizing methods
public Dimension getPreferredSize()
{
return new Dimension(WIDTH, HEIGHT);
}
public Dimension getMaximumSize() { return getPreferredSize(); }
public Dimension getMinimumSize() { return getPreferredSize(); }
}
答案 0 :(得分:2)
您的示例代码与您绘制的图片不匹配,并且它不使用GridBagLayout。 SSCCE
应该使用您测试的代码复制问题。
问题是您的自定义对象的实现。您真正需要的是类中的自定义属性,它反映了组件的当前状态。类似的东西:
public void setLargeSize(Boolean largeSize)
{
this.largeSize = largeSize;
revalidate();
repaint();
}
然后你需要修改getPreferredSize()方法以根据这个变量返回组件的大小:
@Override
public Dimension getPreferredSize()
{
if (largeSize)
return new Dimension(WIDTH, HEIGHT);
else
return new Dimension(WIDTH - 30, HEIGHT - 30);
}
现在,布局管理器可以根据组件的当前状态完成其工作。
您还可以更改您的绘画代码。绘图代码不需要检查按下状态,因为布局管理器已经考虑了这一点。实际上,我不会'认为你甚至需要覆盖paintComponent()。只需设置按钮的一些属性:
setBorderPainted( false );
setContentAreaPainted( false );
setFocusPainted( false );
然后,您可以在setLargeSize(...)方法中设置背景颜色。
最后,MouseListener将使用适当的参数调用setLargeSize(...)
方法。
所以现在您需要做的就是确保正确设置约束,以便组件在其单元格中居中。您可能需要设置组件的对齐x / y。
答案 1 :(得分:-2)
也许您可以尝试更改按钮的界限,具体取决于它是缩小的尺寸还是全尺寸?只有当您的主窗口不可调整大小时才会这样。
Component.setBounds(int x,int y,int width,int height)