2

I'm working on a simple javaFX desktop software, it essentially allow a user to control various lights via serial communication. It's composed of three classes:

  • he UI Controller (written using javaFX scene builder 2.0 and a custom library for material-like controls, jfoenix)
  • a "Storage" object with static properties (like which light is on and what color it should display), this class must contain only static properites, so that there are no conflicts with other objects trying to modify some values. This object is also responsable for the serial communication (using jssc)
  • A threaded object that controls lights using timers

I must say that i have a working solution built using swing, but i honestly don't like it at all...

Here's the compiled UI: https://i.stack.imgur.com/UM0so.jpg

There are two problems:

  • I want that each button on the top (like "barra 1") displays the status of the corrisponding light, for example, if "barra 1" is on, it should be green, when it's off, it should be red. the problem here is that i have to create an object of the controller class in order to access to all the buttons, but as it should be, in the instantiated object, all the buttons are gone, i should recreate them, and that's obivuosly not the solution... what can i do?
  • That's simple, I already know that my "listener" is incorrect, but I just can't find the mistake... as soon as I drag any of the sliders, a Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: argument type mismatch exception is thrown... (and there's no reference to any of my classes)

Here you can find the code:

Storage class

package com.matteoformenti.rgbcontroller;

import java.awt.*;

/**
 * Created by Matteo on 28/12/2015.
 */
public class Storage
{
    private static final String ON_COLOR = "#4CAF50";
    private static final String OFF_COLOR = "#F44336";

    private static Color color;
    private static boolean bars[] = {false, false, false, false, false};
    private static boolean circles[] = new boolean[2];
    private static boolean usePot = false;

    //-------------------------------------------------------//


    public static boolean getBarValue(int barNumber)
    {
        return bars[barNumber];
    }

    public static void setAllBars(boolean value)
    {
        for(boolean v : bars)
            v = value;
        setAllBarsColors();
    }

    public static boolean[] getAllBars()
    {
        return bars;
    }

    public static void setCircleValue(int circleNumber, boolean value)
    {
        circles[circleNumber-1] = value;
    }

    public static boolean getCircleValue(int circleNumber)
    {
        return circles[circleNumber-1];
    }

    public static void setAllCircles(boolean value)
    {
        for(boolean v : circles)
            v = value;
    }

    public static boolean[] getAllCircles()
    {
        return circles;
    }

    public static void setColor(Color c)
    {
        color = c;
    }

    public static void setRed(int red)
    {
        if(red > 255)
            red = 255;
        if(red < 0)
            red = 0;
        int g = color.getGreen();
        int b = color.getBlue();
        color = new Color(red, g, b);
    }

    public static void setGreen(int green)
    {
        if(green > 255)
            green = 255;
        if(green < 0)
            green = 0;
        int r = color.getRed();
        int b = color.getBlue();
        color = new Color(r, green, b);
    }

    public static void setBlue(int blue)
    {
        if(blue > 255)
            blue = 255;
        if(blue < 0)
            blue = 0;
        int g = color.getGreen();
        int r = color.getRed();
        color = new Color(r, g, blue);
    }

    public static void setHue(int h)
    {
        int rgb = Color.HSBtoRGB(h, 100, 100);
        int red = (rgb >> 16) & 0xFF;
        int green = (rgb >> 8) & 0xFF;
        int blue = rgb & 0xFF;
        color = new Color(red, green, blue);
    }

    public static void invertBarValue(int i)
    {
        bars[i] = !bars[i];
        setBarColor(i);
    }
    public static void invertCircleValue(int i)
    {
        circles[i] = !circles[i];
    }

    public static void setBarColor(int i)
    {
        Controller c = new Controller();
        c.test();
        /*Controller.bar1.setStyle("-fx-background-color: " + ON_COLOR + ";");
        if (bars[i] == true)
            Controller.getBarButton(i).setStyle("-fx-background-color: " + ON_COLOR + ";");
        if (bars[i] == false)
            Controller.getBarButton(i).setStyle("-fx-background-color: " + OFF_COLOR + ";");*/
    }

    public static void setAllBarsColors()
    {/*
        for (int i = 0; i < 5; i++)
        {
            if (bars[i] == true)
                Controller.getBarButton(i + 1).setStyle("-fx-background-color: " + ON_COLOR + ";");
            if (bars[i] == false)
                Controller.getBarButton(i + 1).setStyle("-fx-background-color: " + OFF_COLOR + ";");
        }*/
    }
}

Controller class:

package com.matteoformenti.rgbcontroller;

import com.jfoenix.controls.JFXButton;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ColorPicker;
import javafx.scene.control.Slider;
import javafx.scene.layout.Background;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;

import java.awt.*;

public class Controller
{

    @FXML
    private JFXButton bar1;

    @FXML
    private JFXButton bar2;

    @FXML
    private JFXButton bar3;

    @FXML
    private JFXButton bar4;

    @FXML
    private JFXButton bar5;

    @FXML
    private JFXButton circle1;

    @FXML
    private JFXButton circle2;

    @FXML
    private Slider rSlider;

    @FXML
    private Slider gSlider;

    @FXML
    private Slider bSlider;

    @FXML
    private Slider aSlider;

    @FXML
    private JFXButton pot;

    @FXML
    private JFXButton stroboBars;

    @FXML
    private Button stroboBarsConfig;

    @FXML
    private JFXButton stroboCircles;

    @FXML
    private Button stroboCirclesConfig;

    @FXML
    private JFXButton fadeColors;

    @FXML
    private Button fadeColorsConfig;

    @FXML
    private ColorPicker colorPicker;

    @FXML
    private Pane frame;

    public void test()
    {
        bar1.setStyle("-fx-background-color: #33b5e5;");
    }

    @FXML
    void bar1Pressed(ActionEvent event)
    {
        Storage.invertBarValue(0);
    }

    @FXML
    void bar2Pressed(ActionEvent event) {Storage.invertBarValue(1);}

    @FXML
    void bar3Pressed(ActionEvent event)
    {
        Storage.invertBarValue(2);
    }

    @FXML
    void bar4Pressed(ActionEvent event) {Storage.invertBarValue(3);}

    @FXML
    void bar5Pressed(ActionEvent event) {Storage.invertBarValue(4);}

    @FXML
    void circle1Pressed(ActionEvent event) {
    }

    @FXML
    void circle2Pressed(ActionEvent event) {

    }

    @FXML
    void potPressed(ActionEvent event) {

    }

    @FXML
    void rSliderChanged(ActionEvent event)
    {
    }

    @FXML
    void gSliderChanged(ActionEvent event) {

    }

    @FXML
    void bSliderChanged(ActionEvent event) {

    }

    @FXML
    void aSliderChanged(ActionEvent event) {

    }

    @FXML
    void colorPickerChanged(ActionEvent event)
    {
        Color colorAWT = Utility.javaFXtoAWTColor(colorPicker.getValue());
        frame.setStyle("-fx-background-color: #" + colorPicker.getValue().toString().substring(2,8) + ";");
    }

    @FXML
    void stroboBarsPressed(ActionEvent event) {

    }

    @FXML
    void stroboBarsConfigPressed(ActionEvent event) {

    }

    @FXML
    void stroboCirclesPressed(ActionEvent event) {

    }

    @FXML
    void stroboCirclesConfigPressed(ActionEvent event) {

    }

    @FXML
    void fadeColorsPressed(ActionEvent event) {

    }

    @FXML
    void fadeColorsConfigPressed(ActionEvent event) {

    }
}

And the fxml layout

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.paint.*?>
<?import com.jfoenix.controls.*?>
<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>


<Pane fx:id="frame" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="260.0" prefWidth="620.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.matteoformenti.rgbcontroller.Controller">
   <children>
      <HBox fx:id="buttonsBox1" layoutY="30.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="40.0" prefWidth="620.0">
         <children>
            <JFXButton fx:id="bar1" alignment="CENTER" buttonType="RAISED" onAction="#bar1Pressed" ripplerFill="WHITE" style="-fx-background-color: #F44336;" text="Barra 1">
               <font>
                  <Font name="Roboto Light" size="12.0" />
               </font>
               <HBox.margin>
                  <Insets bottom="10.0" left="10.0" right="5.0" top="10.0" />
               </HBox.margin>
            </JFXButton>
            <JFXButton fx:id="bar2" alignment="CENTER" buttonType="RAISED" layoutX="20.0" layoutY="20.0" onAction="#bar2Pressed" ripplerFill="WHITE" style="-fx-background-color: #F44336;" text="Barra 2">
               <font>
                  <Font name="Roboto Light" size="12.0" />
               </font>
               <HBox.margin>
                  <Insets bottom="10.0" left="5.0" right="5.0" top="10.0" />
               </HBox.margin>
            </JFXButton>
            <JFXButton fx:id="bar3" alignment="CENTER" buttonType="RAISED" layoutX="80.0" layoutY="10.0" onAction="#bar3Pressed" ripplerFill="WHITE" style="-fx-background-color: #F44336;" text="Barra 3">
               <font>
                  <Font name="Roboto Light" size="12.0" />
               </font>
               <HBox.margin>
                  <Insets bottom="10.0" left="5.0" right="5.0" top="10.0" />
               </HBox.margin>
            </JFXButton>
            <JFXButton fx:id="bar4" alignment="CENTER" buttonType="RAISED" layoutX="135.0" layoutY="10.0" onAction="#bar4Pressed" ripplerFill="WHITE" style="-fx-background-color: #F44336;" text="Barra 4">
               <font>
                  <Font name="Roboto Light" size="12.0" />
               </font>
               <HBox.margin>
                  <Insets bottom="10.0" left="5.0" right="5.0" top="10.0" />
               </HBox.margin>
            </JFXButton>
            <JFXButton fx:id="bar5" alignment="CENTER" buttonType="RAISED" layoutX="190.0" layoutY="10.0" onAction="#bar5Pressed" ripplerFill="WHITE" style="-fx-background-color: #F44336;" text="Barra 5">
               <font>
                  <Font name="Roboto Light" size="12.0" />
               </font>
               <HBox.margin>
                  <Insets bottom="10.0" left="5.0" right="5.0" top="10.0" />
               </HBox.margin>
            </JFXButton>
            <JFXButton fx:id="circle1" alignment="CENTER" buttonType="RAISED" layoutX="280.0" layoutY="20.0" onAction="#circle1Pressed" ripplerFill="WHITE" style="-fx-background-color: #F44336;" text="Cerchio 1">
               <font>
                  <Font name="Roboto Light" size="12.0" />
               </font>
               <HBox.margin>
                  <Insets bottom="10.0" left="20.0" right="5.0" top="10.0" />
               </HBox.margin>
            </JFXButton>
            <JFXButton fx:id="circle2" alignment="CENTER" buttonType="RAISED" layoutX="340.0" layoutY="10.0" onAction="#circle2Pressed" ripplerFill="WHITE" style="-fx-background-color: #F44336;" text="Cerchio 2">
               <font>
                  <Font name="Roboto Light" size="12.0" />
               </font>
               <HBox.margin>
                  <Insets left="5.0" right="5.0" top="10.0" />
               </HBox.margin>
            </JFXButton>
            <JFXButton fx:id="pot" alignment="CENTER" buttonType="RAISED" layoutX="395.0" layoutY="10.0" onAction="#potPressed" ripplerFill="WHITE" style="-fx-background-color: #F44336;" text="Potenziometri">
               <font>
                  <Font name="Roboto Light" size="12.0" />
               </font>
               <HBox.margin>
                  <Insets left="20.0" top="10.0" />
               </HBox.margin>
            </JFXButton>
         </children>
      </HBox>
      <HBox alignment="CENTER" fillHeight="false" layoutY="80.0" prefHeight="40.0" prefWidth="620.0">
         <children>
            <VBox prefHeight="200.0" prefWidth="100.0" HBox.hgrow="ALWAYS">
               <children>
                  <Label alignment="CENTER" contentDisplay="CENTER" prefHeight="17.0" prefWidth="135.0" text="Rosso" textAlignment="CENTER" />
                  <Slider fx:id="rSlider" max="255.0" onDragDetected="#rSliderChanged" value="128.0" />
               </children>
               <HBox.margin>
                  <Insets left="10.0" right="10.0" />
               </HBox.margin>
            </VBox>
            <VBox prefHeight="200.0" prefWidth="100.0" HBox.hgrow="ALWAYS">
               <children>
                  <Label alignment="CENTER" contentDisplay="CENTER" prefHeight="17.0" prefWidth="135.0" text="Verde" textAlignment="CENTER" />
                  <Slider fx:id="gSlider" max="255.0" onDragDetected="#gSliderChanged" value="128.0" />
               </children>
               <HBox.margin>
                  <Insets left="10.0" right="10.0" />
               </HBox.margin>
            </VBox>
            <VBox layoutX="110.0" layoutY="10.0" prefHeight="200.0" prefWidth="100.0" HBox.hgrow="ALWAYS">
               <children>
                  <Label alignment="CENTER" contentDisplay="CENTER" prefHeight="17.0" prefWidth="135.0" text="Blu" textAlignment="CENTER" VBox.vgrow="ALWAYS" />
                  <Slider fx:id="bSlider" max="255.0" onDragDetected="#bSliderChanged" value="128.0" />
               </children>
               <HBox.margin>
                  <Insets left="10.0" right="10.0" />
               </HBox.margin>
            </VBox>
            <VBox layoutX="210.0" layoutY="10.0" prefHeight="200.0" prefWidth="100.0" HBox.hgrow="ALWAYS">
               <children>
                  <Label alignment="CENTER" contentDisplay="CENTER" prefHeight="17.0" prefWidth="135.0" text="Luminosità" textAlignment="CENTER" />
                  <Slider fx:id="aSlider" max="255.0" onDragDetected="#aSliderChanged" value="128.0" />
               </children>
               <HBox.margin>
                  <Insets left="10.0" right="10.0" />
               </HBox.margin>
            </VBox>
         </children>
      </HBox>
      <ColorPicker fx:id="colorPicker" layoutX="10.0" layoutY="130.0" onAction="#colorPickerChanged" prefHeight="25.0" prefWidth="600.0" />
      <HBox alignment="TOP_CENTER" layoutY="175.0" prefHeight="50.0" prefWidth="620.0">
         <children>
            <HBox prefHeight="50.0" prefWidth="150.0">
               <children>
                  <JFXButton fx:id="stroboBars" alignment="CENTER" buttonType="RAISED" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onAction="#stroboBarsPressed" ripplerFill="WHITE" style="-fx-background-color: #F44336;" text="Strobo Barre" textAlignment="CENTER" HBox.hgrow="ALWAYS">
                     <HBox.margin>
                        <Insets bottom="10.0" left="10.0" right="5.0" top="10.0" />
                     </HBox.margin>
                  </JFXButton>
                  <Button fx:id="stroboBarsConfig" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#stroboBarsConfigPressed" prefHeight="25.0" prefWidth="25.0" style="-fx-background-color: #33b5e5;" textFill="#33b5e5">
                     <HBox.margin>
                        <Insets bottom="10.0" right="10.0" top="10.0" />
                     </HBox.margin>
                  </Button>
               </children>
            </HBox>
            <HBox layoutX="150.0" layoutY="10.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="50.0" prefWidth="150.0">
               <children>
                  <JFXButton fx:id="stroboCircles" alignment="CENTER" buttonType="RAISED" onAction="#stroboCirclesPressed" ripplerFill="WHITE" style="-fx-background-color: #F44336;" text="Strobo Cerchi" textAlignment="CENTER" HBox.hgrow="ALWAYS">
                     <HBox.margin>
                        <Insets bottom="10.0" left="10.0" right="5.0" top="10.0" />
                     </HBox.margin>
                  </JFXButton>
                  <Button fx:id="stroboCirclesConfig" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#stroboCirclesConfigPressed" prefHeight="25.0" prefWidth="25.0" style="-fx-background-color: #33b5e5;" textFill="#33b5e5">
                     <HBox.margin>
                        <Insets bottom="10.0" right="10.0" top="10.0" />
                     </HBox.margin>
                  </Button>
               </children>
            </HBox>
            <HBox layoutX="320.0" layoutY="10.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="50.0" prefWidth="150.0">
               <children>
                  <JFXButton fx:id="fadeColors" alignment="CENTER" buttonType="RAISED" onAction="#fadeColorsPressed" ripplerFill="WHITE" style="-fx-background-color: #F44336;" text="Strobo Cerchi" textAlignment="CENTER" HBox.hgrow="ALWAYS">
                     <HBox.margin>
                        <Insets bottom="10.0" left="10.0" right="5.0" top="10.0" />
                     </HBox.margin>
                  </JFXButton>
                  <Button fx:id="fadeColorsConfig" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#fadeColorsConfigPressed" prefHeight="25.0" prefWidth="25.0" style="-fx-background-color: #33b5e5;" textFill="#33b5e5">
                     <HBox.margin>
                        <Insets bottom="10.0" right="10.0" top="10.0" />
                     </HBox.margin>
                  </Button>
               </children>
            </HBox>
         </children>
      </HBox>
   </children>
</Pane>

Thanks a ton for your help, have a nice day!! Formenti Matteo

  • 1
    You shouldn't create a new instance of the controller class. You should get the already loaded one from the `FXMLLoader` - see here http://stackoverflow.com/questions/10751271/accessing-fxml-controller-class As to your second question - I don't really understand what the question is, or which method you are referring to. – Itai Dec 29 '15 at 23:53
  • Thank you!! That's what i was searching for!!! This is what happens as soon as i drag any of the sliders http://pastebin.com/JdDJ0GvR – Formenti Matteo Dec 29 '15 at 23:56
  • Unrelated, but never import java.awt or javax.swing classes in a JavaFX application unless you really need to you (and you probably don't need to). – jewelsea Dec 30 '15 at 21:01

1 Answers1

1

The exception you are getting is because you are trying to hook a MouseEvent handler to an ActionEvent handler - see here. Changing the argument type to MouseEvent should get rid of the exception.

However! this event deals with drag-and-drop, which is probably not what you are after! See this tutorial - you should either bind to the value property of the slider, or add a ChangeListener to it.

Itai
  • 6,641
  • 6
  • 27
  • 51