feltersnach
feltersnach

Reputation: 406

JLabel on JPanel poitioning

I have been trying to get some JLabels to number rows on a JPanel for a couple days now with no joy. I have tried every layout manager I can think of. Currently I have the best results (which aren't what I want) with the GridLayout. Please help!

The area in question is the AddLabels() method.

Question: How can I get the JLabels in the code below to line up with each row?

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.util.*;
import java.util.List;

@SuppressWarnings("serial")
public class DrawPanelMain extends JPanel {

    private static final int PREF_W = 1200;
    private static final int PREF_H = 700;

    //Points for Ellipse2D
    private List<Point> POINT_LIST = Arrays.asList(
            new Point(60, 40),
            new Point(60, 100),
            new Point(60, 160),
            new Point(60, 220),
            new Point(60, 280),
            new Point(60, 340),
            new Point(60, 400),
            new Point(60, 460),
            new Point(60, 520),
            new Point(60, 580),
            new Point(120, 100),
            new Point(120, 160),
            new Point(120, 220),
            new Point(120, 280),
            new Point(120, 340),
            new Point(120, 400),
            new Point(120, 460),
            new Point(120, 520),
            new Point(120, 580),
            new Point(180, 160),
            new Point(180, 220),
            new Point(180, 280),
            new Point(180, 340),
            new Point(180, 400),
            new Point(180, 460),
            new Point(180, 520),
            new Point(180, 580),
            new Point(240, 220),
            new Point(240, 280),
            new Point(240, 340),
            new Point(240, 400),
            new Point(240, 460),
            new Point(240, 520),
            new Point(240, 580),
            new Point(300, 280),
            new Point(300, 340),
            new Point(300, 400),
            new Point(300, 460),
            new Point(300, 520),
            new Point(300, 580),
            new Point(360, 340),
            new Point(360, 400),
            new Point(360, 460),
            new Point(360, 520),
            new Point(360, 580),
            new Point(420, 400),
            new Point(420, 460),
            new Point(420, 520),
            new Point(420, 580),
            new Point(480, 460),
            new Point(480, 520),
            new Point(480, 580),
            new Point(540, 520),
            new Point(540, 580),
            new Point(600, 580));

    //Points for labels
    private List<Point> POINT_LIST2 = Arrays.asList(
            new Point (20, 40),
            new Point (20, 100),
            new Point (20, 160));

    private JTabbedPane tabbedPane = new JTabbedPane();
    private int tabIndex = 0;

    public DrawPanelMain() {
        JPanel btnPanel = new JPanel();
        JPanel infoPanel = new JPanel();
        btnPanel.add(new JButton(new AddSwitchAction("Add Switch Panel")));
        btnPanel.add(new JButton(new PushConfigAction("Push Config")));
        btnPanel.add(new JButton(new ActivateAllAction("Activate All")));
        infoPanel.add(new JTextField(20));

        setLayout(new BorderLayout());
        add(tabbedPane, BorderLayout.CENTER);
        add(btnPanel, BorderLayout.PAGE_END);
        add(infoPanel, BorderLayout.EAST);
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    private class AddSwitchAction extends AbstractAction {
            public AddSwitchAction(String name) {
                super(name);
                int mnemonic = (int) name.charAt(0);
                putValue(MNEMONIC_KEY, mnemonic);
            }

        @Override
        public void actionPerformed(ActionEvent e) {
            tabIndex++;
            String title = "Switch " + tabIndex;
            DrawPanel2 tabComponent = new DrawPanel2(POINT_LIST);
            DrawLabels tabComponent2 = new DrawLabels(POINT_LIST2);
            tabbedPane.add(title, tabComponent);
        }
    }

    private class PushConfigAction extends AbstractAction {
        public PushConfigAction(String name) {
            super(name);
            int mnemonic = (int) name.charAt(0);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            /*Add code sending the configuration to the switch panel*/
            JOptionPane.showMessageDialog(DrawPanelMain.this, "Configuration Pushed to Panel");
        }
    }

    private class ActivateAllAction extends AbstractAction {
        public ActivateAllAction(String name) {
            super(name);
            int mnemonic = (int) name.charAt(1);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            Component comp = tabbedPane.getSelectedComponent();
            if (comp instanceof DrawPanel2) {
                DrawPanel2 drawPanel = (DrawPanel2) comp;
                drawPanel.activateAll();
            }
        }
    }

    private static void createAndShowGui() {
        DrawPanelMain mainPanel = new DrawPanelMain();
        final double version = 0.1;
        JFrame frame = new JFrame("RF Connection Panel " + version);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

}

@SuppressWarnings("serial")
class DrawPanel2 extends JPanel {
    private static final int OVAL_WIDTH = 30;
    private static final Color INACTIVE_COLOR = Color.RED;
    private static final Color ACTIVE_COLOR = Color.green;
    private List<Point> points;
    private List<Ellipse2D> ellipses = new ArrayList<>();
    private Map<Ellipse2D, Color> ellipseColorMap = new HashMap<>();

    public DrawPanel2(List<Point> points) {
        this.points = points;
        for (Point p : points) {
            int x = p.x - OVAL_WIDTH / 2;
            int y = p.y - OVAL_WIDTH / 2;
            int w = OVAL_WIDTH;
            int h = OVAL_WIDTH;
            Ellipse2D ellipse = new Ellipse2D.Double(x, y, w, h);
            ellipses.add(ellipse);
            ellipseColorMap.put(ellipse, INACTIVE_COLOR);
        }

        MyMouseAdapter mListener = new MyMouseAdapter();
        addMouseListener(mListener);
        addMouseMotionListener(mListener);
        setLayout(new GridLayout(12, 4, 0, 0));
        setBorder(new EmptyBorder(10, 10, 0, 0));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        for (Ellipse2D ellipse : ellipses) {
            g2.setColor(ellipseColorMap.get(ellipse));
            g2.fill(ellipse);
        }
    }

    private class MyMouseAdapter extends MouseAdapter {
        @Override
        public void mousePressed(MouseEvent e) {
            for (Ellipse2D ellipse : ellipses) {
                if (ellipse.contains(e.getPoint())) {
                    Color c = ellipseColorMap.get(ellipse);
                    c = (c == INACTIVE_COLOR) ? ACTIVE_COLOR : INACTIVE_COLOR;
                    ellipseColorMap.put(ellipse, c);
                }
            }
            repaint();
        }
    }

    public void activateAll() {
        for (Ellipse2D ellipse : ellipses) {
            ellipseColorMap.put(ellipse, ACTIVE_COLOR);
        }
        repaint();
    }
}

@SuppressWarnings("serial")
class DrawLabels extends JPanel {
    private List<Point> points2;
    private List<JLabel> jLabels = new ArrayList<>();
    private int i = 0;

    public DrawLabels(List<Point> points2) {
        this.points2 = points2;
        for (Point p : points2) {
            JLabel jLabel = new JLabel("Row" + i);
            jLabels.add(jLabel);
            i++;
        }
    }
}

Upvotes: 0

Views: 55

Answers (2)

MadProgrammer
MadProgrammer

Reputation: 347184

The problem you have is trying to fight the difference in font metrics between different systems, which will typically make the labels always slightly different. Even with a layout manager, it would be difficult to do as a single unit of work, instead...

You could...

Create a custom JPanel whose sole responsibility would be to draw a single row of dots. You could then add a JLabel and this to a row using something like GridLayout or GridBagLayout

You could...

Draw the row numbers directly onto the panel with the dots using Graphics#drawString

Upvotes: 2

user4668606
user4668606

Reputation:

Simply add another JPanel for each line:

JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel , BoxLayout.Y_AXIS));

for(JLabel[] line : labels){
    JPanel lp = new JPanel();
    lp.setLayout(new BoxLayout(lp , BoxLayout.X_AXIS));
    mainPanel.add(lp);

    for(JLabel label : line)
        lp.add(label);
}

This way you can combine multiple layoutmanagers to match your requirements. Or create your own LayoutManager (http://docs.oracle.com/javase/tutorial/uiswing/layout/custom.html)

Upvotes: 1

Related Questions