Java 如何根据二维网格上的路径为线设置不同的颜色

Java 如何根据二维网格上的路径为线设置不同的颜色,java,swing,2d,Java,Swing,2d,我有一个简单的程序,从一个单元到另一个单元绘制线,形成一条路径。我有两组路径:一组由红细胞形成,另一组由蓝细胞形成。 我一次只能设置一种颜色,这两种颜色都适用 现在我要做的是设置线条的颜色以匹配单元格的颜色,每组都有自己的线条颜色。我使用自定义绘画在玻璃窗格上用以下代码绘制线条: @Override public void paintComponent(Graphics g) { super.paintComponent(g); Graphic

我有一个简单的程序,从一个单元到另一个单元绘制线,形成一条路径。我有两组路径:一组由红细胞形成,另一组由蓝细胞形成。 我一次只能设置一种颜色,这两种颜色都适用

现在我要做的是设置线条的颜色以匹配单元格的颜色,每组都有自己的线条颜色。我使用自定义绘画在
玻璃窗格
上用以下代码绘制线条:

 @Override
    public void paintComponent(Graphics g) {    
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setColor(Color.RED); //Lines' Color is set here
        g2d.setStroke(new BasicStroke(3));

        for(List<JLabel> line : lines) {

            for(int i=0; i <(line.size()) ; i++) {
                JLabel label1 = line.get(i);
                int n = (i == (line.size()-1)) ? 0: i+1;
                JLabel label2 = line.get(n);
                g2d.draw(new Line2D.Float(getCenter(label1), getCenter(label2)));
            }
        }

        g2d.dispose();
    }

我建议采取以下办法:
修改
Token
enum,使其保存颜色和图标信息:

enum Token {

    VIDE (Color.WHITE), CERCLE_BLEU (Color.BLUE), CERCLE_ROUGE(Color.RED);

    private static final int ICON_W = 21;
    public Color color;
    public Icon icon;

    Token(Color color) {

        this.color = color;
        icon = createIcon(color);
    }

    private Icon createIcon(Color color) {

        BufferedImage img = new BufferedImage(ICON_W, ICON_W, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = img.createGraphics();
        g2.setColor(color);
        g2.fillOval(1, 1, ICON_W - 2, ICON_W - 2);
        g2.dispose();

        return new ImageIcon(img);
    }
}
子类
JLabel
创建可使用
令牌初始化的
JLabel

class TLabel extends JLabel{

    Token token;
    TLabel(Token token) {
        setToken(token);
    }

    void setToken(Token token) {

        this.token = token;
        setIcon(token.icon);
        setPreferredSize(new Dimension(
                token.icon.getIconWidth(), token.icon.getIconHeight()));
    }
    Token getToken() {
        return token;
    }

    Color getColor() {
        return token.color;
    }
}

请注意,
TLabel
的实例包含
Token
和颜色信息,具有适当的图标和正确的首选大小。
在应用程序中使用
TLabel
,如下所示:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class Example extends JPanel {

    private TLabel[][] grid;

    List<TLabel> redCels = new ArrayList<>();
    List<TLabel> blueCells  = new ArrayList<>();
    List<List<TLabel>> paths = new ArrayList<>();

    Example(int rows, int cols) {

        setLayout(new GridLayout(rows, cols, 1, 1));
        setBorder(BorderFactory.createLineBorder(Color.BLACK));
        setBackground(Color.BLACK);
        createGrid(rows, cols);
        setTestData();
    }

    void createGrid(int rows, int cols) {

        grid = new TLabel[rows][cols];
        for (int r = 0; r < grid.length; r++) {
            for (int c = 0; c < grid[r].length; c++) {
                grid[r][c] = new TLabel(Token.VIDE);
                grid[r][c].setOpaque(true);
                grid[r][c].setBackground(Color.WHITE);
                add(grid[r][c]);
            }
        }
    }

    void setTestData() {

        //test data
        set(11, 3, Token.CERCLE_ROUGE);
        set(10, 2, Token.CERCLE_ROUGE);
        set(9, 3, Token.CERCLE_ROUGE);
        set(10, 4, Token.CERCLE_ROUGE);

        set(8, 13, Token.CERCLE_BLEU);
        set(9, 12, Token.CERCLE_BLEU);
        set(10, 13, Token.CERCLE_BLEU);
        set(9, 14, Token.CERCLE_BLEU);

        paths.add(redCels); paths.add(blueCells);
    }

    void set(int row, int col, Token token) {

        grid[row][col].setToken(token);

        if(token == Token.CERCLE_ROUGE) {
            redCels.add(grid[row][col]);
        }else {
            blueCells.add(grid[row][col]);
        }
    }

    private List<List<TLabel>> getPahs() {
        return paths;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {

                JFrame frame = new JFrame("TEST CASE");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                Example example = new Example(20, 20);
                frame.add(example);
                DrawLines glassPane = new DrawLines(example.getPahs());
                frame.setGlassPane(glassPane);
                frame.getGlassPane().setVisible(true);
                frame.setLocationRelativeTo(null);
                frame.pack();
                frame.setResizable(false);
                frame.setVisible(true);
            }
        });
    }


}

enum Token {

    VIDE (Color.WHITE), CERCLE_BLEU (Color.BLUE), CERCLE_ROUGE(Color.RED);

    private static final int ICON_W = 21;
    public Color color;
    public Icon icon;

    Token(Color color) {

        this.color = color;
        icon = createIcon(color);
    }

    private Icon createIcon(Color color) {

        BufferedImage img = new BufferedImage(ICON_W, ICON_W, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = img.createGraphics();
        g2.setColor(color);
        g2.fillOval(1, 1, ICON_W - 2, ICON_W - 2);
        g2.dispose();

        return new ImageIcon(img);
    }
}

class TLabel extends JLabel{

    Token token;
    TLabel(Token token) {
        setToken(token);
    }

    void setToken(Token token) {

        this.token = token;
        setIcon(token.icon);
        setPreferredSize(new Dimension(
                token.icon.getIconWidth(), token.icon.getIconHeight()));
    }
    Token getToken() {
        return token;
    }

    Color getColor() {
        return token.color;
    }
}

//used as glass pane to draw lines
class DrawLines extends JPanel {

    private List<List<TLabel>> lines;
    DrawLines(List<List<TLabel>> lines) {

        this.lines = lines;
        setOpaque(false);
    }

    @Override
    public void paintComponent(Graphics g) {

        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setStroke(new BasicStroke(3));

        for(List<TLabel> line : lines) {

            //use color information from TLabel
            //the whole path is of the same color so do it one per path
            g2d.setColor(line.get(0).getColor());

            for(int i=0; i <(line.size()) ; i++) {
                TLabel label1 = line.get(i);
                int n = (i == (line.size()-1)) ? 0: i+1;
                TLabel label2 = line.get(n);
                g2d.draw(new Line2D.Float(getCenter(label1), getCenter(label2)));
            }
        }

        g2d.dispose();
    }
import java.awt.BasicStroke;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.GridLayout;
导入java.awt.Point;
导入java.awt.geom.Line2D;
导入java.awt.image.buffereImage;
导入java.util.ArrayList;
导入java.util.List;
导入javax.swing.BorderFactory;
导入javax.swing.Icon;
导入javax.swing.ImageIcon;
导入javax.swing.JComponent;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JPanel;
导入javax.swing.SwingUtilities;
公共类示例扩展了JPanel{
专用TLabel[][]网格;
List redCels=new ArrayList();
List blueCells=new ArrayList();
列表路径=新的ArrayList();
示例(int行、int列){
setLayout(新的GridLayout(行、列、1、1));
setboorder(BorderFactory.createLineBorder(Color.BLACK));
挫折背景(颜色:黑色);
创建网格(行、列);
setTestData();
}
void createGrid(整数行、整数列){
网格=新的TLabel[行][列];
对于(int r=0;r对于(int i=0;请注意,发布[mvce]也需要所有导入,我认为这是不必要的,因为IDE可以添加它们
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class Example extends JPanel {

    private TLabel[][] grid;

    List<TLabel> redCels = new ArrayList<>();
    List<TLabel> blueCells  = new ArrayList<>();
    List<List<TLabel>> paths = new ArrayList<>();

    Example(int rows, int cols) {

        setLayout(new GridLayout(rows, cols, 1, 1));
        setBorder(BorderFactory.createLineBorder(Color.BLACK));
        setBackground(Color.BLACK);
        createGrid(rows, cols);
        setTestData();
    }

    void createGrid(int rows, int cols) {

        grid = new TLabel[rows][cols];
        for (int r = 0; r < grid.length; r++) {
            for (int c = 0; c < grid[r].length; c++) {
                grid[r][c] = new TLabel(Token.VIDE);
                grid[r][c].setOpaque(true);
                grid[r][c].setBackground(Color.WHITE);
                add(grid[r][c]);
            }
        }
    }

    void setTestData() {

        //test data
        set(11, 3, Token.CERCLE_ROUGE);
        set(10, 2, Token.CERCLE_ROUGE);
        set(9, 3, Token.CERCLE_ROUGE);
        set(10, 4, Token.CERCLE_ROUGE);

        set(8, 13, Token.CERCLE_BLEU);
        set(9, 12, Token.CERCLE_BLEU);
        set(10, 13, Token.CERCLE_BLEU);
        set(9, 14, Token.CERCLE_BLEU);

        paths.add(redCels); paths.add(blueCells);
    }

    void set(int row, int col, Token token) {

        grid[row][col].setToken(token);

        if(token == Token.CERCLE_ROUGE) {
            redCels.add(grid[row][col]);
        }else {
            blueCells.add(grid[row][col]);
        }
    }

    private List<List<TLabel>> getPahs() {
        return paths;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {

                JFrame frame = new JFrame("TEST CASE");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                Example example = new Example(20, 20);
                frame.add(example);
                DrawLines glassPane = new DrawLines(example.getPahs());
                frame.setGlassPane(glassPane);
                frame.getGlassPane().setVisible(true);
                frame.setLocationRelativeTo(null);
                frame.pack();
                frame.setResizable(false);
                frame.setVisible(true);
            }
        });
    }


}

enum Token {

    VIDE (Color.WHITE), CERCLE_BLEU (Color.BLUE), CERCLE_ROUGE(Color.RED);

    private static final int ICON_W = 21;
    public Color color;
    public Icon icon;

    Token(Color color) {

        this.color = color;
        icon = createIcon(color);
    }

    private Icon createIcon(Color color) {

        BufferedImage img = new BufferedImage(ICON_W, ICON_W, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = img.createGraphics();
        g2.setColor(color);
        g2.fillOval(1, 1, ICON_W - 2, ICON_W - 2);
        g2.dispose();

        return new ImageIcon(img);
    }
}

class TLabel extends JLabel{

    Token token;
    TLabel(Token token) {
        setToken(token);
    }

    void setToken(Token token) {

        this.token = token;
        setIcon(token.icon);
        setPreferredSize(new Dimension(
                token.icon.getIconWidth(), token.icon.getIconHeight()));
    }
    Token getToken() {
        return token;
    }

    Color getColor() {
        return token.color;
    }
}

//used as glass pane to draw lines
class DrawLines extends JPanel {

    private List<List<TLabel>> lines;
    DrawLines(List<List<TLabel>> lines) {

        this.lines = lines;
        setOpaque(false);
    }

    @Override
    public void paintComponent(Graphics g) {

        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setStroke(new BasicStroke(3));

        for(List<TLabel> line : lines) {

            //use color information from TLabel
            //the whole path is of the same color so do it one per path
            g2d.setColor(line.get(0).getColor());

            for(int i=0; i <(line.size()) ; i++) {
                TLabel label1 = line.get(i);
                int n = (i == (line.size()-1)) ? 0: i+1;
                TLabel label2 = line.get(n);
                g2d.draw(new Line2D.Float(getCenter(label1), getCenter(label2)));
            }
        }

        g2d.dispose();
    }