【问题标题】:Overlapping AWT lines and Swing JLabels重叠 AWT 线和 Swing JLabel
【发布时间】:2011-12-21 09:05:11
【问题描述】:

我的应用程序使用线原语和JLables 时遇到问题。我试着解释一下:

  • 我必须绘制一条车辆路线,用线表示道路,JLabels 表示城市。我需要使用JLabels,因为每个 JLabel 都有一个侦听器,它显示一个包含城市信息的对话框。
  • 我重新定义了我的主要JPanelpaint() 方法。在该方法中,我首先调用super.paint(),然后绘制线条,最后将标签添加到JPanel

问题在于线条与标签重叠,无论绘制它们的顺序如何。有什么建议吗?

【问题讨论】:

  • 以防自己不是的目标:在野外有很好的开放、免费和易于使用的框架 - f.i. JUNG(手边没有链接,抱歉)

标签: java swing awt jlabel overlapping


【解决方案1】:

您还可以覆盖JPanelpaintComponent()paintChildren() 方法。 在paintChildren()调用你的画线然后superJLabels

【讨论】:

  • +1,自定义绘画是通过覆盖paintComponent()方法完成的,而不是paint()。然后在自定义绘制完成后绘制子标签。
【解决方案2】:

另一种方式应该是

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;

public class AddVertexDemo {

    public AddVertexDemo() {
    }

    private static void createAndShowUI() {
        JFrame frame = new JFrame("AddVertexDemo");
        frame.getContentPane().add(new Gui().getMainPanel());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                createAndShowUI();
            }
        });
    }
}

class DrawingPanel extends JPanel {

    private static final int RADIUS = 6;
    private static final long serialVersionUID = 1L;
    private List<Shape> vertexList = new ArrayList<Shape>();

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        if (vertexList.size() > 1) {
            Shape s0 = vertexList.get(0);
            Shape s1 = null;
            for (int i = 0; i < vertexList.size(); i++) {
                s1 = vertexList.get(i);
                drawConnectingLine(g, s0, s1);
                s0 = s1;
            }
            s1 = vertexList.get(0);
            //drawConnectingLine(g2, s0, s1);
        }
        for (Shape shape : vertexList) {
            g2.setColor(Color.blue);
            g2.fill(shape);
            g2.setColor(Color.blue.darker().darker());
            g2.draw(shape);
        }
    }

    private void drawConnectingLine(Graphics g, Shape s0, Shape s1) {
        Rectangle r0 = s0.getBounds();
        Rectangle r1 = s1.getBounds();
        int x0 = r0.x + r0.width / 2;
        int y0 = r0.y + r0.height / 2;
        int x1 = r1.x + r1.width / 2;
        int y1 = r1.y + r1.height / 2;
        g.drawLine(x0, y0, x1, y1);
    }

    public void addVertex(Point p) {
        int x = p.x - RADIUS;
        int y = p.y - RADIUS;
        int w = 2 * RADIUS;
        int h = w;
        vertexList.add(new Ellipse2D.Double(x, y, w, h));
        repaint();
    }

    public void removeVertex(Point p) {
        if (vertexList.size() > 0) {
            for (int i = vertexList.size() - 1; i >= 0; i--) {
                if (vertexList.get(i).contains(p)) {
                    vertexList.remove(i);
                    repaint();
                    return;
                }
            }
        }
    }
}

 class Gui {

    private static final Dimension DRAWING_PANEL_SIZE = new Dimension(600, 500);
    private JPanel mainPanel = new JPanel(new BorderLayout());
    private DrawingPanel drawingPanel = new DrawingPanel();
    private JToggleButton addVertexBtn = new JToggleButton("Add Vertex");
    private JToggleButton removeVertexBtn = new JToggleButton("Remove Vertex");

    Gui() {
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(addVertexBtn);
        buttonPanel.add(removeVertexBtn);
        DrawPanelMouseListener mouseListener = new DrawPanelMouseListener();
        mouseListener.setDrawingPanel(drawingPanel);
        mouseListener.setGui(this);
        drawingPanel.addMouseListener(mouseListener);
        drawingPanel.setPreferredSize(DRAWING_PANEL_SIZE);
        drawingPanel.setBorder(BorderFactory.createLineBorder(Color.black));
        mainPanel.add(drawingPanel, BorderLayout.CENTER);
        mainPanel.add(buttonPanel, BorderLayout.SOUTH);
    }

    public JPanel getMainPanel() {
        return mainPanel;
    }

    public boolean isAddingVertex() {
        return addVertexBtn.isSelected();
    }

    public boolean isRemovingVertex() {
        return removeVertexBtn.isSelected();
    }

    public void setAddingVertex(boolean addingVertex) {
        addVertexBtn.setSelected(addingVertex);
    }

    public void setRemovingVertex(boolean removingVertex) {
        removeVertexBtn.setSelected(removingVertex);
    }
}

class DrawPanelMouseListener extends MouseAdapter {

    private DrawingPanel drawingPanel;
    private Gui gui;

    public DrawPanelMouseListener() {
    }

    public void setGui(Gui gui) {
        this.gui = gui;
    }

    public void setDrawingPanel(DrawingPanel drawingPanel) {
        this.drawingPanel = drawingPanel;
    }

    @Override
    public void mousePressed(MouseEvent me) {
        if (gui.isAddingVertex() && gui.isRemovingVertex()) {
            gui.setAddingVertex(false);
            gui.setRemovingVertex(false);
            return;
        }
        if (gui.isAddingVertex()) {
            drawingPanel.addVertex(me.getPoint());
            gui.setAddingVertex(false);
        }
        if (gui.isRemovingVertex()) {
            drawingPanel.removeVertex(me.getPoint());
            gui.setRemovingVertex(false);
        }
    }
}

【讨论】:

    【解决方案3】:

    我不确定这是否是正确的方法,但你可以试试这个:

    1. 创建 2 个面板。一个用于绘制线条,另一个用于绘制建筑物(标签)。
    2. LayeredPaneJFrame 中添加两个面板。在下层添加带有线条的面板,然后添加带有标签的面板。

    您也可以通过其他方式使用LayeredPanes 来解决您的问题。在此处了解更多信息:How to use Layered Panes in java

    【讨论】:

      猜你喜欢
      • 2016-05-17
      • 2014-06-14
      • 2011-11-16
      • 2015-04-24
      • 1970-01-01
      • 2016-01-23
      • 2010-09-29
      • 2011-12-06
      • 1970-01-01
      相关资源
      最近更新 更多