Disclaimer: This code is for an assignment. Granted, the question I'm asking doesn't have anything to do with the assignment's requirements (it doesn't specify needing any sort of layout), but I wanted to mention that.
My assignment is to create a GUI displaying a rectangle with it's color able to be changed through three sliders (RGB), as well as three text fields displaying each slider's current value (0-255). I've managed to find a way to set up the sliders and textFields in the positions I want them through an array, but I have no idea how to add the rectangle to a slot on that array (or if I even can). The code I have currently also draws the rectangle as two intersecting lines rather than a solid block. Would that have something to do with my layout?
package ExercisePackage;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import javax.swing.JFrame;
public class MyColorChooser extends JPanel {
// Holds int values
private int red = 255;
private int green = 255;
private int blue = 255;
// Holds color sliders
private JSlider redSlider;
private JSlider greenSlider;
private JSlider blueSlider;
// Holds slider text numbers
private JTextField redText;
private JTextField greenText;
private JTextField blueText;
// Create rectangle
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(new Color(red, green, blue));
g.fillRect(15, 25, 100, 20);
}
public MyColorChooser()
{
// Create and set layout array for specific cell placement
int rows = 3;
int columns = 3;
JPanel[][] panelHolder = new JPanel[rows][columns];
setLayout(new GridLayout(rows, columns, 5, 5));
// Formula for cell placement
for(int m = 0; m < rows; m++) {
for(int n = 0; n < columns; n++) {
panelHolder[m][n] = new JPanel();
add(panelHolder[m][n]);
}
}
// Create sliders
redSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 0);
redSlider.addChangeListener(new SliderListener());
greenSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 0);
greenSlider.addChangeListener(new SliderListener());
blueSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 0);
blueSlider.addChangeListener(new SliderListener());
// Create text fields
redText = new JTextField("0", 3);
redText.setEditable(false);
greenText = new JTextField("0", 3);
greenText.setEditable(false);
blueText = new JTextField("0", 3);
blueText.setEditable(false);
// Add sliders and text fields
panelHolder[0][0].add(redSlider);
panelHolder[0][1].add(greenSlider);
panelHolder[0][2].add(blueSlider);
panelHolder[1][0].add(redText);
panelHolder[1][1].add(greenText);
panelHolder[1][2].add(blueText);
}
// Inner class to handle event changes when the slider is moved
private class SliderListener implements ChangeListener {
public void stateChanged(ChangeEvent e)
{
// Link color values to slider
red = redSlider.getValue();
green = greenSlider.getValue();
blue = blueSlider.getValue();
// Link text field values to slider
redText.setText(Integer.toString(red));
greenText.setText(Integer.toString(green));
blueText.setText(Integer.toString(blue));
// Link rectangle color to sliders
repaint();
}
}
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setContentPane( new MyColorChooser() );
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
It's not clear why you have the JPanel[][]
at all your issue appears to be that you adding a bunch of components to a JPanel, that also paints a color box. So the you want to make a new JPanel that paints the color box, and add that to your component.
The first change is to replace your paintComponent with a JPanel.
JPanel colorPanel = new JPanel(){
// Create rectangle
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(new Color(red, green, blue));
g.fillRect(15, 25, 100, 20);
}
@Override
public Dimension getPreferredSize(){
//should be fixed.
return new Dimension(115, 45);
}
}
Then add that component to your layout in the constructor (I am not a fan of doing so much gui work in the constructor.)
//... continuing of constructor.
panelHolder[1][0].add(redText);
panelHolder[1][1].add(greenText);
panelHolder[1][2].add(blueText);
panelHolder[2][0].add(colorPanel);
}
I have now made a component that draws a rectangle and added it to the original layout. Some issues.