简体   繁体   English

如何具体更改 JList 的一行的颜色?

[英]How to specifically change the Color of one row of a JList?

I'm in need of help since i cant get my head around this problem.我需要帮助,因为我无法解决这个问题。 I want to ping ip's and if they are reacheable then the specific row should be green and if theres no answer it should be red.我想 ping ip,如果它们可以访问,那么特定的行应该是绿色的,如果没有答案,它应该是红色的。 Also it changes the color after i added another ip, not at the same time, which I haven't fixed yet.在我添加另一个 ip 之后它也会改变颜色,但不是同时,我还没有修复。 Any help would be awesome with both problems.对于这两个问题,任何帮助都会很棒。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextArea;
import javax.swing.JButton;

public class ListColorRed extends JFrame implements ActionListener {
    static JTextArea ipInput;
    private JPanel contentPane;
    static JButton addBtn;
    static DefaultListModel<String> model = new DefaultListModel<>();
    static List<String> ipList = new ArrayList<String>();
    static JList<String> jList;
    static boolean isIpResponding = false;
    private JScrollPane scrollPane;
    static Color background;
    static Color foreground;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                jList = new JList<String>(model);
                ListColorRed lcr = new ListColorRed();
                repeatTask();
                jList.setCellRenderer(new DefaultListCellRenderer() {
                    @Override
                    public Component getListCellRendererComponent(JList<?> list, Object value, int index,
                            boolean isSelected, boolean cellHasFocus) {
                        super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                        try {

                            if (isIpResponding == true) {
                                background=Color.GREEN;
                                foreground=Color.WHITE;
                            } else {
                                background=Color.RED;
                                foreground=Color.WHITE;
//  did that code before| if (isIpResponding == false)
//                              setBackground(Color.RED);
                            }
                        } catch (Exception e) {
                            // TODO: handle exception
                        }
                        setBackground(background);
                        setForeground(foreground);
                        return this;

                    }
                });
                lcr.setVisible(true);


            }
        });
    }

    /**
     * Create the frame.
     */
    public ListColorRed() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBackground(Color.WHITE);
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        addBtn = new JButton("Add");
        addBtn.setBounds(250, 75, 89, 23);
        contentPane.add(addBtn);
        addBtn.addActionListener(this);
        JPanel panel = new JPanel();
        panel.setBackground(Color.BLUE);
        panel.setBounds(10, 51, 230, 66);
        contentPane.add(panel);
        panel.setLayout(null);

        ipInput = new JTextArea();
        ipInput.setBounds(10, 11, 210, 44);
        panel.add(ipInput);

        scrollPane = new JScrollPane();
        scrollPane.setBounds(20, 128, 219, 88);
        contentPane.add(scrollPane);

        jList = new JList<String>();
        scrollPane.setViewportView(jList);
        jList.setBackground(Color.WHITE);
        jList.setValueIsAdjusting(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object knopfHorcher = e.getSource();
        if (knopfHorcher == addBtn) {
            ipList.add(ipInput.getText());
            jList.setModel(model);
            model.addElement(ipInput.getText());

            ipInput.setText("");
        }
    }

    public static boolean pingRequest() throws IOException {
        for (int i = 0; i < model.size(); i++) {
            InetAddress zielAdresse = InetAddress.getByName(ipList.get(i));
            System.out.println("Sending Ping Request to " + ipList.get(i));

            if (zielAdresse.isReachable(5000)) {
                System.out.println("Respond");
                isIpResponding = true;
            } else {
                System.out.println("No respond");
                isIpResponding = false;
            }
        }
        return isIpResponding;
    }

    public static void repeatTask() {
        int minuten = 1;
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                try {
                    pingRequest();

                } catch (Exception e) {

                }
            }
        }, 0, 100 * 50 * minuten);

    }

}

I've tried to use booleans and I've tried to put the addresses in an ArrayList so its seperated.我尝试使用布尔值,并尝试将地址放在 ArrayList 中,以便将其分开。

Introduction介绍

Read @camickr's comment.阅读@camickr 的评论。 Take his advice to heart.把他的建议记在心里。

Oracle has a helpful tutorial, Creating a GUI With Swing . Oracle 有一个有用的教程,使用 Swing 创建 GUI Skip the Learning Swing with the NetBeans IDE section.跳过学习 Swing 和 NetBeans IDE 部分。

I revised your GUI.我修改了你的图形用户界面。 Here's a test result.这是一个测试结果。

网络回应

Explanation解释

When I create a Swing GUI, I use the model-view-controller (MVC) pattern.当我创建 Swing GUI 时,我使用model-view-controller (MVC) 模式。 This pattern allows me to separate my concerns and focus on one part of the application at a time.这种模式使我能够分离我的关注点并一次专注于应用程序的一部分。

By making use of classes and methods I can further separate my concerns and focus on a smaller part of the application.通过使用类和方法,我可以进一步分离我的关注点并专注于应用程序的较小部分。

The first thing I did was create an application model. An application model consists of one or more plain Java getter/setter classes.我做的第一件事是创建一个应用程序 model。应用程序 model 由一个或多个普通的 Java getter/setter 类组成。

Model Model

A JList can accept any Object , so I created a WebResponse class that holds a web address and a boolean that tells me whether or not a response happened. JList可以接受任何Object ,所以我创建了一个WebResponse class ,它包含一个 web 地址和一个 boolean 告诉我是否发生了响应。

I created a WebResponseModel class to hold a DefaultListModel .我创建了一个WebResponseModel class 来保存DefaultListModel I used a DefaultListModel because I was using a JList .我使用DefaultListModel因为我使用的是JList

View看法

All Swing applications must start with a call to the SwingUtilities invokeLater method.所有 Swing 应用程序都必须以调用SwingUtilities invokeLater方法开始。 This method ensures that the Swing components are created and executed on the Event Dispatch Thread .此方法确保 Swing 组件在Event Dispatch Thread上创建和执行。

I separated the creation of the JFrame from the creation of the JPanel and JScrollPane .我将JFrame的创建与JPanelJScrollPane的创建分开了。 I have difficulty understanding code that's all jumbled up in one method.我很难理解在一种方法中混杂在一起的代码。

The JFrame has a default BorderLayout , which I used. JFrame有一个我使用的默认BorderLayout I managed the closing of the JFrame myself so I could stop the Swing Timer .我自己管理了JFrame的关闭,所以我可以停止 Swing Timer

The entry JPanel uses a FlowLayout .条目JPanel使用FlowLayout

I separated the ListCellRenderer code into its own class.我将ListCellRenderer代码分离到它自己的 class 中。

Controller Controller

I used a Swing Timer to control the testing of the web addresses, rather than a utility Timer .我使用 Swing Timer来控制 web 地址的测试,而不是实用程序Timer The ActionListener of the Swing Timer uses a method defined in the WebResponse model class. Swing TimerActionListener使用了WebResponse model class中定义的方法。

The "Add" JButton ActionListener is a lambda because all it does is add the web address to the DefaultListModel . “添加” JButton ActionListener是一个 lambda,因为它所做的只是将 web 地址添加到DefaultListModel

Code代码

There are no static fields.没有 static 字段。 There is a minimum amount of class fields.最少有 class 个字段。 Each method does one thing.每个方法做一件事。

Here's the complete runnable code.这是完整的可运行代码。 I made the additional classes inner classes so I could post the code as one block.我制作了额外的类内部类,这样我就可以将代码作为一个块发布。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.InetAddress;

import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class WebResponseGUI implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new WebResponseGUI());
    }

    private final WebResponseModel model;

    private JButton addButton;

    private JFrame frame;

    private JTextField webAddressField;

    private Timer timer;

    public WebResponseGUI() {
        this.model = new WebResponseModel();
    }

    @Override
    public void run() {
        frame = new JFrame("Web Response GUI");
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent event) {
                exitApplication();
            }
        });

        frame.add(createEntryPanel(), BorderLayout.NORTH);
        frame.add(createListPanel(), BorderLayout.CENTER);
        frame.getRootPane().setDefaultButton(addButton);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);

        timer = new Timer(60_000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                DefaultListModel<WebResponse> listModel = model.getListModel();
                for (int index = 0; index < listModel.size(); index++) {
                    WebResponse webResponse = listModel.getElementAt(index);
                    webResponse.checkWebAddress();
                }
            }
        });
        timer.start();
    }

    public void exitApplication() {
        timer.stop();
        frame.dispose();
        System.exit(0);
    }

    private JPanel createEntryPanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));

        JLabel label = new JLabel("Web Address:");
        panel.add(label);

        webAddressField = new JTextField(40);
        panel.add(webAddressField);

        addButton = new JButton("Add");
        addButton.addActionListener(event -> {
            String address = webAddressField.getText().trim();
            if (!address.isEmpty()) {
                model.addWebResponse(new WebResponse(address));
                webAddressField.setText("");
            }
            webAddressField.requestFocusInWindow();
        });
        panel.add(addButton);

        return panel;
    }

    private JScrollPane createListPanel() {
        JList<WebResponse> list = new JList<>(model.getListModel());
        list.setBackground(Color.WHITE);
        list.setCellRenderer(new WebResponseCellRenderer());
        JScrollPane scrollPane = new JScrollPane(list);

        return scrollPane;
    }

    public class WebResponseCellRenderer
            implements ListCellRenderer<WebResponse> {

        @Override
        public Component getListCellRendererComponent(
                JList<? extends WebResponse> list, WebResponse value, int index,
                boolean isSelected, boolean cellHasFocus) {
            JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 0));
            JLabel label = new JLabel(value.toString());
            Color background = Color.RED;
            Color foreground = Color.WHITE;
            if (value.isReachable()) {
                background = Color.GREEN;
                foreground = Color.BLACK;
            }
            panel.setBackground(background);
            label.setBackground(background);
            label.setForeground(foreground);
            panel.add(label);

            return panel;
        }

    }

    public class WebResponseModel {

        private final DefaultListModel<WebResponse> listModel;

        public WebResponseModel() {
            this.listModel = new DefaultListModel<>();
        }

        public void addWebResponse(WebResponse webResponse) {
            listModel.addElement(webResponse);
        }

        public DefaultListModel<WebResponse> getListModel() {
            return listModel;
        }

    }

    public class WebResponse {

        private boolean isReachable;

        private final String webAddress;

        public WebResponse(String webAddress) {
            this.webAddress = webAddress;
            checkWebAddress();
        }

        public void checkWebAddress() {
            try {
                InetAddress zielAdresse = InetAddress.getByName(webAddress);
                this.isReachable = zielAdresse.isReachable(5000);
            } catch (IOException e) {
                this.isReachable = false;
            }
        }

        public boolean isReachable() {
            return isReachable;
        }

        @Override
        public String toString() {
            return webAddress;
        }

    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM