package tim.prune.gui.colour; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import tim.prune.I18nManager; /** * Class to offer a dialog to choose a colour. * Normally a JColorChooser would be used, but this is too buggy * in Java 1.6 and extremely prone to thread-locking, meaning * that the application has to be killed (and all data lost). */ public class ColourChooser { /** main dialog object */ private JDialog _dialog = null; /** array of three slider objects for rgb */ private JSlider[] _rgbSliders = null; /** array of labels for rgb values */ private JLabel[] _rgbLabels = null; /** colour patch */ private ColourPatch _patch = null; /** chosen colour */ private Color _chosenColour = null; /** * Constructor * @param inParent parent dialog */ public ColourChooser(JDialog inParent) { _dialog = new JDialog(inParent, I18nManager.getText("dialog.colourchooser.title"), true); _dialog.setLocationRelativeTo(inParent); _dialog.getContentPane().add(makeContents()); _dialog.pack(); } /** * Make the dialog contents * @return JPanel containing dialog elements */ private JPanel makeContents() { JPanel mainPanel = new JPanel(); mainPanel.setLayout(new BorderLayout()); _rgbSliders = new JSlider[3]; _rgbLabels = new JLabel[3]; _patch = new ColourPatch(Color.WHITE); JPanel centrePanel = new JPanel(); centrePanel.setLayout(new BorderLayout()); centrePanel.add(_patch, BorderLayout.CENTER); JPanel sliderPanel = new JPanel(); sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.Y_AXIS)); final String[] labelKeys = {"red", "green", "blue"}; for (int i=0; i<3; i++) { String key = I18nManager.getText("dialog.colourchooser." + labelKeys[i]); sliderPanel.add(new JLabel(key)); _rgbSliders[i] = new JSlider(0, 255); _rgbSliders[i].addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent arg0) { updatePatch(); } }); _rgbSliders[i].setToolTipText(key); JPanel sliderHolder = new JPanel(); sliderHolder.setLayout(new BorderLayout(5, 0)); sliderHolder.add(_rgbSliders[i], BorderLayout.CENTER); _rgbLabels[i] = new JLabel("255"); _rgbLabels[i].setPreferredSize(new Dimension(40, 1)); sliderHolder.add(_rgbLabels[i], BorderLayout.EAST); sliderPanel.add(sliderHolder); } centrePanel.add(sliderPanel, BorderLayout.SOUTH); mainPanel.add(centrePanel, BorderLayout.CENTER); // Button panel for ok, cancel JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); JButton okButton = new JButton(I18nManager.getText("button.ok")); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { _chosenColour = _patch.getBackground(); _dialog.setVisible(false); } }); buttonPanel.add(okButton); JButton cancelButton = new JButton(I18nManager.getText("button.cancel")); cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { _chosenColour = null; _dialog.setVisible(false); } }); buttonPanel.add(cancelButton); mainPanel.add(buttonPanel, BorderLayout.SOUTH); return mainPanel; } /** * Show the dialog to choose a colour * @param inStartColour current colour */ public void showDialog(Color inStartColour) { // Initialise sliders _rgbSliders[0].setValue(inStartColour.getRed()); _rgbSliders[1].setValue(inStartColour.getGreen()); _rgbSliders[2].setValue(inStartColour.getBlue()); updatePatch(); _dialog.setLocationRelativeTo(_dialog.getParent()); _dialog.setVisible(true); } /** * Update the patch colour from the slider values */ private void updatePatch() { for (int i=0; i<3; i++) { _rgbLabels[i].setText("" + _rgbSliders[i].getValue()); } final Color colour = new Color(_rgbSliders[0].getValue(), _rgbSliders[1].getValue(),_rgbSliders[2].getValue()); _patch.setColour(colour); } /** * @return the selected colour, or null if cancel pressed */ public Color getChosenColour() { return _chosenColour; } }