JavaGUI生成器-如何制作不规则形状的按钮
我一直在使用NetBeans GUI builder,我想做的就是有一张图片(比如一个棒状图形)和一个动作,只有在我单击棒状图形本身时才会发生,而不仅仅是单击它的整个矩形。我在谷歌上搜索了几个小时,什么也找不到,请帮忙 编辑:主要问题是我如何让它忽略按钮上的透明像素JavaGUI生成器-如何制作不规则形状的按钮,java,button,user-interface,builder,Java,Button,User Interface,Builder,我一直在使用NetBeans GUI builder,我想做的就是有一张图片(比如一个棒状图形)和一个动作,只有在我单击棒状图形本身时才会发生,而不仅仅是单击它的整个矩形。我在谷歌上搜索了几个小时,什么也找不到,请帮忙 编辑:主要问题是我如何让它忽略按钮上的透明像素 package my.usefulness; public class usefulness extends javax.swing.JFrame { public usefulness() { i
package my.usefulness;
public class usefulness extends javax.swing.JFrame
{
public usefulness()
{
initComponents();
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jButton1 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jButton1.setIcon(new javax.swing.ImageIcon("C:\\Users\\rando_000\\Desktop\\buttonImage.png")); // NOI18N
jButton1.setBorderPainted(false);
jButton1.setContentAreaFilled(false);
jButton1.setFocusPainted(false);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(149, 149, 149)
.addComponent(jButton1)
.addContainerGap(200, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jButton1)
.addGap(0, 237, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
}
包我的有用性;
公共类扩展javax.swing.JFrame
{
公共效用()
{
初始化组件();
}
@抑制警告(“未选中”)
//
私有组件(){
jButton1=newjavax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jButton1.setIcon(新的javax.swing.ImageIcon(“C:\\Users\\rando\u 000\\Desktop\\buttonImage.png”);//NOI18N
jButton1.1(假);
jButton1.setContentAreaFilled(false);
jButton1.setfocuspaint(假);
javax.swing.GroupLayout=newjavax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(布局);
layout.setHorizontalGroup(
createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(149149149)
.addComponent(jButton1)
.addContainerGap(200,简称最大值))
);
layout.setVerticalGroup(
createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jButton1)
.addGap(0,237,短。最大值))
);
包装();
}//
}
Swing本身无法处理非矩形形状的单击事件(据我所知)。您可以尝试捕捉单击事件上的鼠标位置,并计算此xy坐标是否在形状内部
我不知道你的图像是什么样子,但我猜它是透明背景上的某种图形。如果是这样,您可以简单地检查该xy坐标处的像素颜色是否为该特定背景色
这样你就有了一个简单快速的算法。。。我不认为这是最好的,但也许已经足够好了:)没有“不规则形状的按钮”这样的东西,反正我也不知道。。。你得自己做
这里的问题是,您可能会混淆图像和java组件。我的意思是,java无法确定图像中的兴趣点,这就是为什么图像被视为矩形。如果使用flash、photoshop或任何高级绘图工具,那么它有点像矢量和图像之间的区别
无论如何,为了解决您的问题,您可以定义一个与您的棍形形状相同的多边形。为此,请定义构成多边形的点,如下所示:
//a triangle for example
int[] x = {100,50,150}; // the X postion of the points that form the polygon
int[] y = {100,200,200};// the y pos
Polygon pol = new Polygon(x,y,3) // 3 is number of points .
现在在鼠标事件侦听器中:
public void mouseClicked(MouseEvent evt){
{
if(pol.contains(evt.getPoint()){
// do w.e your button should do
}
}
现在这样,如果鼠标单击事件在多边形pol(应该是你的棒状图形)内,那么你可以按按钮的意图操作我自己对此有点好奇,所以我尝试创建一种新的组件类型。我采取的方法是,当你点击这个组件时,它应该用图像像素数据检查鼠标事件的位置,如果像素是透明的,那么鼠标事件不应该被注册。这个实现只处理鼠标按下事件,类还远未完成,但它应该给您一个好的开始!签出我放在那里的
TODO
标记
public class TransparentImageButton extends JComponent implements MouseListener {
private BufferedImage image = null;
private File imageFile;
private List<ActionListener> listeners;
public TransparentImageButton(File imageFile) throws IOException {
this.imageFile = imageFile;
this.image = ImageIO.read(imageFile);
this.addMouseListener(this);
this.listeners = new ArrayList<ActionListener>();
}
public void addActionListener(ActionListener listener) {
listeners.add(listener);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Rectangle r = getImageBounds();
g.drawImage(image, r.x, r.y, r.width, r.height, this);
}
private Rectangle getImageBounds() {
// TODO Add in proper handling if component size < image size.
return new Rectangle((int)((getBounds().width-image.getWidth())/2), (int)((getBounds().height-image.getHeight())/2), image.getWidth(), image.getHeight());
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Add more action events?
}
@Override
public void mousePressed(MouseEvent e) {
Rectangle bounds = getImageBounds();
if(bounds.contains(e.getPoint())) {
int ix = e.getX()-bounds.x;
int iy = e.getY()-bounds.y;
int [] arr = image.getData().getPixel(ix, iy, new int[4]);
// get the alpha for the current pixel
if(arr[3] != 0) {
// not transparent
ActionEvent newActionEvent = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, imageFile.getName(), e.getWhen(), e.getModifiers());
for(ActionListener listener : listeners) {
listener.actionPerformed(newActionEvent);
}
}
} else {
}
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Add more action events?
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Add more action events?
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Add more action events?
}
}
并使用此图像:
好吧,您可以在
onClick()中获取鼠标X,Y。这不是一个好主意,但如果你绝望了……你希望如何区分图上的位置和图上的位置?这将是你问题的决定性因素。我添加了一个编辑,但问题更多的是如何忽略透明像素,对不起,我本来打算对此进行投票,但你打破了油漆链,这可能会导致一些令人讨厌的油漆artifacts@MadProgrammer哎呀,修好了
public static void main(String[] args) throws FileNotFoundException, IOException {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 400);
frame.setLocationByPlatform(true);
TransparentImageButton btn = new TransparentImageButton(new File("c:\\icon.png"));
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Clicky!!");
}
});
frame.getContentPane().add(btn);
frame.setVisible(true);
}