我正在尝试创建一个包含地图的应用程序(Java)。每个县或州,都需要拥有自己的鼠标悬停,mouseClicked方法等。
我尝试这样做的方法是覆盖扩展JButton的自定义类中的paintComponent和paintBorder方法。代码和结果截图:
public class CustomButton extends JButton implements MouseListener {
private Polygon shape;
private boolean isMouseOver;
private Color buttonColor = new Color(100,100,100);
public CustomButton (Polygon shape,Color buttonColor) {
//this.setText(text);
this.buttonColor = buttonColor;
this.shape = shape;
setContentAreaFilled(false);
addMouseListener(this);
}
@Override
public Dimension getPreferredSize() {
return (new Dimension(120, 120));
}
// Hit detection
public boolean contains(int x, int y) {
return shape.contains(x, y);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
if (isMouseOver && isEnabled()) {
g.setColor(new Color(buttonColor.getRed()+50,buttonColor.getGreen()+50,buttonColor.getBlue()+50));
}else{
g.setColor(buttonColor);
}
g.fillPolygon(shape);
}
protected void paintBorder(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setStroke(new BasicStroke(2));
if (isMouseOver && isEnabled()) {
g2d.setColor(new Color(buttonColor.getRed()-50,buttonColor.getGreen()-50,buttonColor.getBlue()-50));
}else{
g2d.setColor(new Color(buttonColor.getRed()-100,buttonColor.getGreen()-100,buttonColor.getBlue()-100));
}
g2d.drawPolygon(shape);
}
结果:
我想要实现的目标(在油漆中编辑):
我认为这是因为即使我重写了paintComponent方法。这个 只修改JButton内部绘制的内容?所以JButton的边界 长方形?有没有办法来解决这个问题?或者我应该努力实现这一目标 以完全不同的方式?
任何帮助都会很棒!我甚至在OpenGL中看过这个编程。我非常喜欢 经验不多!而且它永远消失!
非常感谢
添
答案 0 :(得分:0)
你可以借助null LayoutManager
来实现这一点:
getPreferredSize()
方法。setLayout(null);
)。为您的按钮设置相同的边界,如下一个:
b1.setBounds(0,0,80,80);
b2.setBounds(0,0,80,80);
同样对于实施按钮点击,您需要使用ActionListener
而不是MouseListener
。
答案 1 :(得分:0)
我认为您不能(轻松地)使用多个组件执行此操作。
相反,您应该只使用包含地图图像的单个JLabel。然后,您需要创建一个要在地图上绘制的形状列表,以表示您所在国家/地区的轮廓。所以你需要
答案 2 :(得分:0)
如何使用OverlayLayout:http://java-swing-tips.blogspot.jp/2012/12/combine-five-jbuttons-to-make.html
import java.awt.*;
import javax.swing.*;
public class CompoundButtonTest {
public JComponent makeUI() {
JPanel p = new JPanel();
p.add(new JButton("JButton"));
p.add(makeCompoundButton(120, 80));
return p;
}
private static JComponent makeCompoundButton(int w, int h) {
final Dimension d = new Dimension(w, h);
JPanel p = new JPanel() {
@Override public Dimension getPreferredSize() {
return d;
}
};
p.setLayout(new OverlayLayout(p));
p.add(new CustomButton(TriangleType.A, d, new Color(0x6464C8)));
p.add(new CustomButton(TriangleType.B, d, new Color(0x64C864)));
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new CompoundButtonTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
enum TriangleType {A, B}
class CustomButton extends JButton {
private final Color buttonColor;
private final TriangleType type;
private final Dimension dim;
private Shape shape;
private int stroke = 3;
public CustomButton(TriangleType type, Dimension d, Color color) {
super();
this.type = type;
this.dim = d;
this.buttonColor = color;
setContentAreaFilled(false);
setBorder(BorderFactory.createEmptyBorder());
setIcon(new Icon() {
@Override public void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D)g.create();
if(getModel().isArmed()) {
g2.setColor(buttonColor.darker());
} else if(isRolloverEnabled() && getModel().isRollover()) {
g2.setColor(buttonColor.brighter());
} else {
g2.setColor(buttonColor);
}
g2.translate(x, y);
g2.fill(shape);
g2.setColor(buttonColor.darker());
g2.setStroke(new BasicStroke((float)stroke));
g2.draw(shape);
g2.dispose();
}
@Override public int getIconWidth() {
return dim.width;
}
@Override public int getIconHeight() {
return dim.height;
}
});
}
private Rectangle rect;
@Override public void paintComponent(Graphics g) {
Rectangle r = getBounds();
if(!r.equals(rect)) {
int v = 8;
int s = stroke/2;
int w = r.width - s;
int h = r.height - s;
if(TriangleType.A==type) {
w -= v;
h -= v;
shape = new Polygon(new int[] {s,w,s}, new int[] {s,s,h}, 3);
} else {
w -= s;
h -= s;
shape = new Polygon(new int[] {w,w,v}, new int[] {v,h,h}, 3);
}
rect = r;
}
super.paintComponent(g);
}
@Override public boolean contains(int x, int y) {
return shape.contains(x, y);
}
}