Search code examples
javaswinggenericscollectionsjcombobox

Java GUI change color through combobox, using collections and objects array


This is an assignment, lots of things (like extending JFrame) are silly ways to do things, but I have to do them that way.

I am creating a program that takes as input "colours.txt" which contains 20 colors in the format

white FFFFFF
yellow FFFF00

A GUI window is created that has a colours combobox and an exit button. The combobox is filled with the word representation of the colors, and when they are clicked, the background of the GUI window gets changed to that color, using the hex value to change the color, not the color name. I have to use a collection to accomplish this. I am rereading through all of this material but I'm genuinely lost in a few areas. Using the following code I am able to create a window and fill the combobox, and I can print the color name to the console if I want to, but code that I thought would work is not working. It is a scope problem, where I don't know how to set this up such that I can write the line

frame.setBackground(Color.decode(jcbColour.getSelectedItem().hex));

or something similar to that.

package cmis242fp;

import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.util.*;
import javax.swing.*;

public class Cmis242fp extends JFrame {
    private JButton jbtExit = new JButton("Exit"); //action button
    private static JComboBox jcbColour = new JComboBox(); //drop down of colors

    public Cmis242fp() {
        JPanel myPanel = new JPanel(new BorderLayout());
        myPanel.add(new JLabel("Select a colour:"));
        myPanel.add(jcbColour, BorderLayout.CENTER);
        myPanel.add(jbtExit, BorderLayout.SOUTH);
        myPanel.setBorder(BorderFactory.createEmptyBorder(100, 100, 100, 100));
        myPanel.setMinimumSize(new Dimension(300,300));
        myPanel.setMaximumSize(new Dimension(700,700));

        jcbColour.setMaximumSize(new Dimension(30,30));
        jcbColour.setMaximumSize(new Dimension(60,60));
        add(myPanel);
        jcbColour.addActionListener(new ComboBoxListener());
        jbtExit.addActionListener(new ButtonListener());
    }

    private class ButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.exit(0);
        }
    }

    private class ComboBoxListener implements ActionListener {
        public void comboAction(Color color) {
            frame.setBackground(color);
        }
        public void actionPerformed(ActionEvent e) {

            //comboAction(Color.decode(jcbColour.getSelectedItem());

        }
    }

    public static class Colour implements Comparable<Colour> {
        private String name;
        private String hex;
        public Colour(String name, String hex) {
            this.name = name;
            this.hex = hex;
        }
        public String ntoString() {return name;}
        public String htoString() {return hex;}
        @Override
        public int compareTo(Colour colour) {
            return this.name.compareTo(colour.name);
        }
        public String toString(){
            return name;
        }
        public String toHex() {
            return hex;
        }
    }

    public static void loadColours(String fileName) {
        java.util.List<Colour> coloursList = new ArrayList<Colour>();

        Scanner inFile = null;
        try {
            inFile = new Scanner(new File(fileName));
            while (inFile.hasNext()) {
                coloursList.add(new Colour(inFile.next(), inFile.next()));
            }
        }
        catch (Exception other) {
            System.out.println(other);
        }
        finally {
            if (inFile != null) {
                inFile.close();
            }
        }

        for(int x = 0; x < coloursList.size(); x++) {
            jcbColour.addItem(coloursList.get(x));
        }
    }

    public static void main(String[] args) {

        String filename = "colours.txt";
        loadColours(filename);
        Cmis242fp frame = new Cmis242fp();
        frame.setSize(350,350);
        frame.setMinimumSize(new Dimension(300,300));
        frame.setMaximumSize(new Dimension(750,750));
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

Solution

  • If you set the frame's background you'll see no difference. The easiest way (that is without changing much of your code) is to set myPanel as a class variable and change your listener to this:

    private class ComboBoxListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            myPanel.setBackground(Color.decode(jcbColour.getSelectedItem().toString()));
        }
    }
    

    Now when you select an item of the combobox the background will change accordingly, but note that the decode method works for strings in the form #XXXXXX, so if you want to use this technique then you'll have to insert only that type of strings to the combobox (including the symbol).