Перекрывающиеся строки AWT и Swing JLabels

У меня проблема в моем приложении с использованием линейных примитивов и JLables. Я пытаюсь объяснить это:

  • Мне нужно нарисовать маршрут автомобиля, используя линии для представления дорог и JLabels для представления городов. Мне нужно использовать JLabels, потому что у каждого JLabel есть Listener, который показывает диалог с информацией о городе.
  • Я переопределяю paint() метод моего основного JPanel. В этом методе я сначала вызываю super.paint(), затем рисую линии и, наконец, добавляю метки к JPanel.

Проблема в том, что линии перекрывают метки независимо от порядка их рисования. Есть ли какие-либо предложения?

введите здесь описание изображения


person Robert    schedule 21.12.2011    source источник
comment
на всякий случай, если делать это самостоятельно не цель: есть хорошие открытые, бесплатные и простые в использовании фреймворки в дикой природе - f.i. JUNG (нет под рукой ссылки, извините)   -  person kleopatra    schedule 21.12.2011


Ответы (3)


Вы также можете переопределить методы paintComponent() или paintChildren() класса JPanel. В paintChildren() вызовите рисование линий, а затем super, чтобы нарисовать JLabels.

person StanislavL    schedule 21.12.2011
comment
+1, пользовательское рисование выполняется путем переопределения метода paintComponent(), а НЕ paint(). Затем дочерние метки будут окрашены после того, как будет выполнено пользовательское рисование. - person camickr; 21.12.2011

другой способ должен быть

введите здесь описание изображения

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);
        }
    }
}
person mKorbel    schedule 21.12.2011

Я не уверен, что это правильный способ сделать это, но вы можете попробовать это:

  1. Создайте 2 панели. Один для рисования линий, а другой для рисования зданий (меток).
  2. Добавьте обе панели в LayeredPane из JFrame. Добавьте панель с линией в нижний слой, затем панель с метками.

Вы можете использовать LayeredPanes и другими способами, чтобы решить вашу проблему. Узнайте больше здесь: Как использовать многоуровневые панели в Java

person Harry Joy    schedule 21.12.2011