1

paintComponent(円弧を使用して別の形式でペイントするために)オーバーライドしてラベルを作成し、パネルに配置しました。すべてが正常に機能しましたが、同じ場所(によって.setlocation)にあるラベルが問題を引き起こしています。

同じ場所に異なる形のラベルが3つあるとします。ABC Aが最初に作成され、次にBが作成され、最後にcが作成されます。Aをクリックすると、関数はAをペイントし、「Aをクリックしました」と表示します。

しかし、BまたはCをクリックすると、Aをクリックしたように動作します。

(スクロールペインにスタックされたパネルにラベルを追加しています)

これが私がラベルを作るコードです

for(int i=0;i<rowcount;i++){
        arcstart = Rawazimuth(azimuth[i]);
                    //custom JLabel to paint it like an arc
        MyLabel FLabel = new MyLabel(100, 50, (int)arcstart,cellid[i],lon[i],lat[i]);
        FLabel.setOpaque(true);
        Dimension LabelSize = new Dimension( 100,50);
        FLabel.setSize(LabelSize);
                    //locate the JLabel to labels location. it might be same or not
        FLabel.setLocation(lon[i], lat[i]);

        MyPanel.add(FLabel);    
}

これは私のカスタムjlabelクラスです

public MyLabel(int W, int H, int start,int outcellid,int lonn, int latt) {
    addMouseListener(this);
    arcsizeW = W;
    arcsizeH = H;
    arcstart = start;
    cellid = outcellid;
    clicked = false;
    lon = lonn;
    lat = latt;
}

@Override
public void paintComponent(Graphics g){
    // true if button is clicked, so paint acordingly
    if(clicked ==true){
       g.setColor(dummyg.getColor());  
   }else{
       g.setColor(Color.blue);
   }
  // draw the arc
   g.fillArc(0, 0,arcsizeW , arcsizeH, arcstart, 60);
}

 //if cell is clicked, change its color to red and print its cellid
@Override
public void mouseClicked(MouseEvent e) {

    System.out.println(cellid);

     dummyg = this.getGraphics();
     dummyg.setColor(Color.red);
    this.paintComponent(dummyg);
    clicked = true;
}// other listener stuff}

では、どうすればこれを防ぐことができますか?私はjlayerpaneを使用できると思いますが、少なくとも4つのレイヤーが必要になります(問題がなければdunno)。

4

3 に答える 3

5

呼び出していることを確認してくださいsuper.paintComponent。これは、コンポーネントがペイント補正されていることを確認するために重要です。

マウスのイベントは雨のようなものです。それらは、マウスイベントを受信して​​停止するように登録された最初のコンポーネントにヒットします(雨が傘に当たるなど)。

オーバーラップするコンポーネントがある場合、それらがオーバーラップする場合、マウスイベントは、それらを処理するために登録された最初のコンポーネント(この場合はA)に移動します。

これが私が何を意味するかを示す簡単な例です...

ここに画像の説明を入力してください ここに画像の説明を入力してください

各円にカーソルを合わせると、ハイライト表示されます。中央にカーソルを合わせてみてください...

public class OverlappingMouseTest {

    public static void main(String[] args) {
        new OverlappingMouseTest();
    }

    public OverlappingMouseTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new BackgroundPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }            
        });
    }

    protected class BackgroundPane extends JLayeredPane {

        private CirclePane redPane;
        private CirclePane greenPane;
        private CirclePane bluePane;

        public BackgroundPane() {            
            redPane = new CirclePane(Color.RED);
            greenPane = new CirclePane(Color.GREEN);
            bluePane = new CirclePane(Color.BLUE);

            add(redPane);
            add(greenPane);
            add(bluePane);            
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        public void doLayout() {            
            Dimension size = new Dimension(100, 100);
            int width = getWidth() - 1;
            int height = getHeight() - 1;

            Point p = new Point();
            p.x = (width / 2) - 50;
            p.y = (height / 2) - 75;            
            redPane.setBounds(new Rectangle(p, size));

            p.x = (width / 2) - 75;
            p.y = (height / 2) - 25;
            bluePane.setBounds(new Rectangle(p, size));

            p.x = (width / 2) - 25;
            p.y = (height / 2) - 25;
            greenPane.setBounds(new Rectangle(p, size));            
        }        
    }

    protected class CirclePane extends JPanel {

        private boolean mouseHover = false;

        public CirclePane(Color background) {
            setOpaque(false);
            setBackground(background);
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseExited(MouseEvent me) {
                    mouseHover = false;
                    repaint();
                }

                @Override
                public void mouseEntered(MouseEvent me) {
                    mouseHover = true;
                    repaint();
                }                
            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(100, 100);
        }

        @Override
        protected void paintComponent(Graphics grphcs) {            
            super.paintComponent(grphcs);

            Graphics2D g2d = (Graphics2D) grphcs.create();
            if (!mouseHover) {
                g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
            }
            g2d.setColor(getBackground());
            g2d.fill(new Ellipse2D.Float(0, 0, getWidth() - 1, getHeight() - 1));
            g2d.dispose();            
        }        
    }    
}
于 2012-10-11T09:00:37.063 に答える
3

すべてが正常に機能しましたが、同じ場所(.setlocationによって)にあるJLabelが問題を引き起こしています。

同じ場所に異なる形状の3つのJlabelがあるとします。ABC Aが最初に作成され、次にBが作成され、最後にcが作成されます。

使用するツリーの方法があります

于 2012-10-11T08:57:21.050 に答える
0

私は自分の問題を解決しました。

私が見つけた本当の問題は、Javaが各コンポーネントをx、yの位置と幅と高さで解釈していることでした。したがって、ラベルが(グラフィカルに)オーバーラップしていなくても、同じコンポーネントとして解釈できます。

問題を解決するために、マウスのクリックポイントとコンポーネントの中心の間の角度を見つけました。次に、最も近いコンポーネントを計算して到達しました。

レイヤーなどはこの状況では機能しません。他の唯一の方法は、実際の形状のcontainsメソッドをオーバーライドすることです。

于 2012-10-20T09:58:01.660 に答える