1

I am making a colour changer using RGB input, and I want to make sure the input's are integers whilst parsing. If one of the RGB values is not parsable, then it should clear that field but keep the fields that parsed fine. My code works but I have to use 3 try/catch statements but I want to reduce it to one. How would I merge all these three if possible?

  • Consider [JFormattedTextField if all you need is integers.](https://docs.oracle.com/javase/tutorial/uiswing/components/formattedtextfield.html) – markspace Oct 25 '17 at 19:27
  • 2
    Extract the three similar blocks of code to a method. Call the method once with red and codeR as argument, then a second time with green and codeG, then a third time with blue and codeB. – JB Nizet Oct 25 '17 at 19:30
  • @JBNizet No need to send in two parameters. Code can also be optimized to not parse each text twice. See [my answer](https://stackoverflow.com/a/46940764/5221149). – Andreas Oct 25 '17 at 19:38
  • Oh yes of course. I iverlooked the fact that red was in fact codeR's text. – JB Nizet Oct 25 '17 at 19:39

3 Answers3

1

How would I merge all these three if possible?

Move common code to helper method. I added value range check too.

private static int getChannelValue(JTextField field) {
    String error;
    try {
        int value = Integer.parseInt(field.getText());
        if (value >= 0 && value <= 255)
            return value;
        error = "Out of range";
    } catch (NumberFormatException f) {
        error = "Not an integer number";
    }
    JOptionPane.showMessageDialog(null, "No. " + error);
    field.setText("");
    return -1; // invalid
}
int r = getChannelValue(codeR);
int g = getChannelValue(codeG);
int b = getChannelValue(codeB);
if (r != -1 && g != -1 && b != -1)
    centreName.setForeground(new Color(r, g, b));
Andreas
  • 154,647
  • 11
  • 152
  • 247
  • Would this be outside my action performed? Oh but it cant go inside action performed since it returns void, hence cant return "value" –  Oct 25 '17 at 19:39
  • @godlypython It can be a method of the `ActionListener` anonymous class *(sibling to `actionPerformed()`)*, or of the top-level class containing all this code, or of an entirely different class *(changing `private` to `public`)*. – Andreas Oct 25 '17 at 19:45
  • Just a question, If i wanted a reset button that cleared the fields and changed the text colour back to original. How would i make it back to the original colour? Because I've created a button listener to set the fields to 0, but idk if jtextfields have a default rgb colour? I tried to repaint but that didn't work. –  Oct 25 '17 at 21:02
  • Nvm, figured it out, just had to set the label foreground colour to null –  Oct 25 '17 at 21:17
0

I assume that you are having all of these values gather once a JButton is clicked? Well, instead of doing that why not store the values when the client is done writing to the TextFields and then use parseInt on that specific field?

field.addFocusListener(new FocusListener() {
            @Override
            public void focusGained(FocusEvent e) { }

            @Override
            public void focusLost(FocusEvent e) {
                // parse and store int here
            }
        });
Aliics
  • 129
  • 6
0

Since Color only accepts integers 0-255, you could instead use a regex

inputString.matches("[12]?\\d?\\d")

The regex accepts 1/2/nothing for the first digit, a number or nothing for the second digit, and requires the third digit

This works for 0-255, but also accepts numbers like 05, 00, and 260 (but not 005, unless you make it [012]), but Integer.parseInt() will figure them out

You may want to also exclude values like 260, which is covered in: Validate if input string is a number between 0-255 using regex

inputString.matches("1?[0-9]{1,2}|2[0-4][0-9]|25[0-5]")) will exclude values like 260, but not 05 or 00

phflack
  • 2,729
  • 1
  • 9
  • 21