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

94 Views Asked by At

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. Also it changes the color after i added another ip, not at the same time, which I haven't fixed yet. 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.

1

There are 1 best solutions below

0
Gilbert Le Blanc On

Introduction

Read @camickr's comment. Take his advice to heart.

Oracle has a helpful tutorial, Creating a GUI With Swing. Skip the Learning Swing with the NetBeans IDE section.

I revised your GUI. Here's a test result.

Web Response

Explanation

When I create a Swing GUI, I use the model-view-controller (MVC) pattern. 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

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.

I created a WebResponseModel class to hold a DefaultListModel. I used a DefaultListModel because I was using a JList.

View

All Swing applications must start with a call to the SwingUtilities invokeLater method. This method ensures that the Swing components are created and executed on the Event Dispatch Thread.

I separated the creation of the JFrame from the creation of the JPanel and JScrollPane. I have difficulty understanding code that's all jumbled up in one method.

The JFrame has a default BorderLayout, which I used. I managed the closing of the JFrame myself so I could stop the Swing Timer.

The entry JPanel uses a FlowLayout.

I separated the ListCellRenderer code into its own class.

Controller

I used a Swing Timer to control the testing of the web addresses, rather than a utility Timer. The ActionListener of the Swing Timer uses a method defined in the WebResponse model class.

The "Add" JButton ActionListener is a lambda because all it does is add the web address to the DefaultListModel.

Code

There are no static fields. There is a minimum amount of class fields. 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;
        }

    }

}