2014-10-10 2 views
2

NetBeans GUI 빌더를 사용하고 있는데 스틱 그림을 말하고 막대기를 클릭했을 때만 수행 할 작업이 있습니다. 전체 사각형뿐만 아니라 그림 그 자체. 나는 몇 시간 동안 봤어 그리고 아무것도 찾을 수 없습니다, 제발 도와주세요!Java GUI 빌더 - 불규칙한 모양의 버튼을 만드는 방법

편집 : 주로 버튼의 투명한 픽셀을 무시하도록 어떻게해야합니까?

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>     
} 
+1

글쎄, 당신은 단지 얻을 수있는 마우스 X ,'onClick()'에 Y가있다. 별로 좋은 생각은 아니지만 절망적이라면 ... – Azar

+0

** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** linebreak **그것은 당신의 문제에서 결정적인 요소가 될 것입니다. – Qix

+0

편집을 추가했지만 투명 픽셀을 무시하는 방법에 대한 질문이 많았습니다. 죄송합니다. –

답변

0

스윙 자체이 아닌 직사각형 형태에 대한 클릭 이벤트를 처리 할 수없는 (내가 아는 한). click 이벤트에서 마우스 위치를 파악하고이 xy 좌표가 모양 안에 있는지 계산할 수 있습니다.

귀하의 이미지가 어떻게 생겼는지는 모르겠지만 그것은 또는 적어도 균일 한 배경 위에 그림이있는 것 같습니다. 그렇다면 단순히 xy 좌표의 픽셀 색상이 특정 배경색인지 아닌지를 확인할 수 있습니다.

당신이 간단하고 빠른 알고리즘을 가지고 그런 식으로 ... 나는 최선을 말할 수 있지만 것만큼 아마 좋은 :)

1

"불규칙한 모양의 버튼을"같은 건하지 그 i가 없다 어쨌든 알고 ... 너 스스로 만들어야 해.

여기에있는 것은 이미지와 Java 구성 요소 사이에 혼동을 줄 수 있습니다. 내 말은 자바가 이미지에 관심의 대상이 무엇인지 결정할 수있는 방법이 없다는 것입니다. 이미지가 사각형으로 간주되는 이유는 무엇입니까? 플래시, 포토샵 또는 기타 고급 그리기 도구로 작업 한 경우 : 차이점과 비슷합니다. 벡터와 이미지 사이.

어쨌든 문제를 해결하기 위해 스틱 그림과 동일한 모양의 Poligon을 정의 할 수 있습니다. 마우스 클릭 이벤트가 다각형 내부에있는 경우,

public void mouseClicked(MouseEvent evt){ 
{ 
    if(pol.contains(evt.getPoint()){ 
    // do w.e your button should do 
    } 
} 

지금이 방법 : 마우스 이벤트 리스너 내부 지금

//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 . 

: 당신이 그렇게처럼 다각형을 구성하는 점의 정의가 수행 폴 (귀하의 스틱 그림이어야합니다), 그럼 당신은 당신의 버튼이 의도하는 것을 할

2

나는 이것에 대해 약간 궁금해서 새로운 컴포넌트 타입을 만들었습니다. 나는이 구성 요소를 클릭 할 때 이미지 픽셀 데이터로 마우스 이벤트 위치를 확인해야합니다. 픽셀이 투명하면 마우스 이벤트를 등록하면 안됩니다. 이 구현은 마우스 다운 이벤트 만 처리하고 클래스는 완전히 완료되지 않았지만 좋은 시작을 제공해야합니다!

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); 
} 

그리고이 이미지 사용 : 내가 거기

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? 
    } 
} 

이 코드를 사용하여 테스트에 넣어 TODO 태그 체크 아웃

Sample button image

+0

투표를 할 예정 이었지만 페인트 끈을 부러 뜨 렸습니다. 더러운 페인트 인공물이 생길 수 있습니다. – MadProgrammer

+0

@MadProgrammer는 –