# Taschenrechnerprojekt in Javafx - Frage zu den Buttons in FXML



## hf_kleineburg (29. Jun 2014)

Hallo, wie kriege ich es hin, dass der Focus um die Buttons (hellblaue Randlinie bei Klick und Auswahl) verschwindet? Ich finde den Styling-Befehl einfach nicht. WÄRE ÜBER KURZE HILFE DANKBAR!
View-Datei "UI.fxml" gebastelt mit dem Scenebuilder 2.0

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

<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.*?>
<?import javafx.scene.effect.*?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<!-- Im folgenden Pane-Element führen die Parameter cacheShape="false" centerShape="false" scaleShape="false" beim Compilieren zum Absturz! -->

<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="308.0" prefWidth="150.0" style="-fx-background-color: #26CCF0;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <GridPane layoutX="10.0" layoutY="52.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="174.0" prefWidth="130.0" style="-fx-border-width: 1; -fx-border-style: solid; -fx-border-radius: 2; -fx-border-color: #FFFFFF;">
        <columnConstraints>
          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
        </columnConstraints>
        <rowConstraints>
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        </rowConstraints>
         <children>
            <Button fx:id="taste1" alignment="CENTER" blendMode="SCREEN" contentDisplay="TEXT_ONLY" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#tasteGeklickt" opacity="0.9" prefHeight="36.0" prefWidth="36.0" text="1" GridPane.halignment="CENTER" GridPane.hgrow="NEVER" GridPane.valignment="CENTER" GridPane.vgrow="NEVER">
               <font>
                  	<Font name="Verdana" size="12.0" />
               </font></Button>
            <Button fx:id="taste2" alignment="CENTER" blendMode="SCREEN" contentDisplay="TEXT_ONLY" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#tasteGeklickt" opacity="0.9" prefHeight="36.0" prefWidth="36.0" text="2" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.hgrow="NEVER" GridPane.valignment="CENTER" GridPane.vgrow="NEVER">
            	<font>
                 	<Font name="Verdana" size="12.0" />
               </font>
               <cursor>
                  <Cursor fx:constant="DEFAULT" />
               </cursor></Button>
            <Button fx:id="taste4" alignment="CENTER" blendMode="SCREEN" contentDisplay="TEXT_ONLY" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#tasteGeklickt" opacity="0.9" prefHeight="36.0" prefWidth="36.0" text="4" GridPane.halignment="CENTER" GridPane.hgrow="NEVER" GridPane.rowIndex="1" GridPane.valignment="CENTER" GridPane.vgrow="NEVER">
            	<font>
                  	<Font name="Verdana" size="12.0" />
               </font></Button>
            <Button fx:id="taste5" alignment="CENTER" blendMode="SCREEN" contentDisplay="TEXT_ONLY" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#tasteGeklickt" opacity="0.9" prefHeight="36.0" prefWidth="36.0" text="5" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.hgrow="NEVER" GridPane.rowIndex="1" GridPane.valignment="CENTER" GridPane.vgrow="NEVER">
            	<font>
                  	<Font name="Verdana" size="12.0" />
               	</font></Button>
            <Button fx:id="taste6" alignment="CENTER" blendMode="SCREEN" contentDisplay="TEXT_ONLY" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#tasteGeklickt" opacity="0.9" prefHeight="36.0" prefWidth="36.0" text="6" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.hgrow="NEVER" GridPane.rowIndex="1" GridPane.valignment="CENTER" GridPane.vgrow="NEVER">
            	<font>
                  	<Font name="Verdana" size="12.0" />
               	</font></Button>
            <Button fx:id="taste7" alignment="CENTER" blendMode="SCREEN" contentDisplay="TEXT_ONLY" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#tasteGeklickt" opacity="0.9" prefHeight="36.0" prefWidth="36.0" text="7" GridPane.halignment="CENTER" GridPane.hgrow="NEVER" GridPane.rowIndex="2" GridPane.valignment="CENTER" GridPane.vgrow="NEVER">
            	<font>
                  	<Font name="Verdana" size="12.0" />
               	</font></Button>
            <Button fx:id="taste8" alignment="CENTER" blendMode="SCREEN" contentDisplay="TEXT_ONLY" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#tasteGeklickt" opacity="0.9" prefHeight="36.0" prefWidth="36.0" text="8" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.hgrow="NEVER" GridPane.rowIndex="2" GridPane.valignment="CENTER" GridPane.vgrow="NEVER">
            	<font>
                  	<Font name="Verdana" size="12.0" />
               	</font></Button>
            <Button fx:id="taste9" alignment="CENTER" blendMode="SCREEN" contentDisplay="TEXT_ONLY" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#tasteGeklickt" opacity="0.9" prefHeight="36.0" prefWidth="36.0" text="9" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.hgrow="NEVER" GridPane.rowIndex="2" GridPane.valignment="CENTER" GridPane.vgrow="NEVER">
            	<font>
                  	<Font name="Verdana" size="12.0" />
               	</font></Button>
            <Button fx:id="taste0" alignment="CENTER" blendMode="SCREEN" contentDisplay="TEXT_ONLY" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#tasteGeklickt" opacity="0.9" prefHeight="36.0" prefWidth="36.0" text="0" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.hgrow="NEVER" GridPane.rowIndex="3" GridPane.valignment="CENTER" GridPane.vgrow="NEVER">
               <font>
                  <Font name="Verdana" size="12.0" />
               </font></Button>
            <Button fx:id="tasteC" alignment="CENTER" blendMode="SCREEN" contentDisplay="TEXT_ONLY" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#tasteGeklickt" opacity="0.9" prefHeight="36.0" prefWidth="36.0" text="C" GridPane.halignment="CENTER" GridPane.hgrow="NEVER" GridPane.rowIndex="3" GridPane.valignment="CENTER" GridPane.vgrow="NEVER">
               <font>
                  <Font name="Verdana" size="12.0" />
               </font></Button>
            <Button fx:id="tasteK" alignment="CENTER" blendMode="SCREEN" contentDisplay="TEXT_ONLY" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#tasteGeklickt" opacity="0.9" prefHeight="36.0" prefWidth="36.0" text="," GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.hgrow="NEVER" GridPane.rowIndex="3" GridPane.valignment="CENTER" GridPane.vgrow="NEVER">
               <font>
                  <Font name="Verdana" size="12.0" />
               </font></Button>
            <Button fx:id="taste3" alignment="CENTER" blendMode="SCREEN" contentDisplay="TEXT_ONLY" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#tasteGeklickt" opacity="0.9" prefHeight="36.0" prefWidth="36.0" text="3" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.hgrow="NEVER" GridPane.valignment="CENTER" GridPane.vgrow="NEVER" />
         </children>
         <padding>
            <Insets bottom="8.0" left="5.0" right="5.0" top="8.0" />
         </padding>
      </GridPane>
      <Label fx:id="ausgabe" alignment="CENTER_RIGHT" contentDisplay="TEXT_ONLY" layoutX="10.0" layoutY="10.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="40.0" prefWidth="130.0" style="-fx-border-width: 1; -fx-border-style: solid; -fx-border-color: #FFFFFF; -fx-border-radius: 3; -fx-label-padding: 0 10 0 10;" text="0" textFill="WHITE">
         <font>
            <Font name="Verdana" size="14.0" />
         </font></Label>
      <VBox layoutX="10.0" layoutY="228.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="70.0" prefWidth="130.0" style="-fx-border-width: 1; -fx-border-style: solid; -fx-border-color: #FFFFFF; -fx-border-radius: 2;">
         <children>
            <HBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="29.0" prefWidth="130.0" VBox.vgrow="NEVER">
               <children>
                  <Button fx:id="tasteA" alignment="CENTER" blendMode="SCREEN" contentDisplay="TEXT_ONLY" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#tasteGeklickt" opacity="0.9" prefHeight="29.0" prefWidth="29.0" text="+" HBox.hgrow="NEVER">
                     <font>
                        <Font name="Verdana" size="10.0" />
                     </font></Button>
                  <Button fx:id="tasteS" alignment="CENTER" blendMode="SCREEN" contentDisplay="TEXT_ONLY" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#tasteGeklickt" opacity="0.9" prefHeight="29.0" prefWidth="29.0" text="-" HBox.hgrow="NEVER">
                     <font>
                        <Font name="Verdana" size="10.0" />
                     </font></Button>
                  <Button fx:id="tasteM" alignment="CENTER" blendMode="SCREEN" contentDisplay="TEXT_ONLY" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#tasteGeklickt" opacity="0.9" prefHeight="29.0" prefWidth="29.0" text="x" HBox.hgrow="NEVER">
                     <font>
                        <Font name="Verdana" size="10.0" />
                     </font></Button>
                  <Button fx:id="tasteD" alignment="CENTER" blendMode="SCREEN" contentDisplay="TEXT_ONLY" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#tasteGeklickt" opacity="0.9" prefHeight="29.0" prefWidth="29.0" text="÷" HBox.hgrow="NEVER">
                     <font>
                        <Font name="Verdana" size="10.0" />
                     </font></Button>
               </children>
            </HBox>
            <Button fx:id="tasteB" alignment="CENTER" blendMode="SCREEN" contentDisplay="TEXT_ONLY" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#tasteGeklickt" opacity="0.9" prefHeight="25.0" prefWidth="116.0" text="=" VBox.vgrow="NEVER">
               <font>
                  <Font name="Verdana" size="12.0" />
               </font>
               <VBox.margin>
                  <Insets top="2.0" />
               </VBox.margin></Button>
         </children>
         <padding>
            <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
         </padding>
      </VBox>
   </children>
   <padding>
      <Insets bottom="20.0" left="10.0" right="10.0" top="20.0" />
   </padding>
</Pane>
```

Und die Controller-Klasse in JavaFX:

```
import java.net.URL;
import java.text.DecimalFormat;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.input.KeyEvent;
import javafx.stage.Stage;

public class Taschenrechner extends Application {
    
	@FXML
    Label ausgabe;
	
	Boolean kommaFlag = false;
	String ausgabePuffer = "";
	double operand = 0;
	double zwischenergebnis = Double.NaN;
	Character letzterOperator = '+';
	DecimalFormat df = new DecimalFormat("########.########");

	
    @FXML
	protected void tasteGeklickt(ActionEvent e) {
	    Button eingabe = (Button)e.getSource();
	    switch (eingabe.getId()) {
        	case "taste0" : this.update(0);
        		break;
        	case "taste1" : this.update(1);
    			break;
        	case "taste2" : this.update(2);
    			break;
        	case "taste3" : this.update(3);
    			break;
        	case "taste4" : this.update(4);
    			break;
        	case "taste5" : this.update(5);
    			break;
        	case "taste6" : this.update(6);
    			break;
        	case "taste7" : this.update(7);
    			break;
        	case "taste8" : this.update(8);
    			break;
        	case "taste9" : this.update(9);
    			break;
        	case "tasteC" : this.update('C');
				break;
        	case "tasteK" : this.update('K');
				break;
        	case "tasteA" : {
        		this.berechne();
        		letzterOperator = '+';
        	}
    			break;
        	case "tasteS" : {
        		this.berechne();
        		letzterOperator = '-';
        	}
				break;
        	case "tasteM" : {
        		this.berechne();
        		letzterOperator = '*';
        	}
				break;
        	case "tasteD" : {
        		this.berechne();
        		letzterOperator = '/';
        	}
				break;
        	case "tasteB" : {
        		this.berechne();
        		letzterOperator = '=';
        	}
				break;
	    }
	}
    
    
    void tastatureingabeVerarbeiten(KeyEvent k) {
    	
	    switch (k.getCode()) {
        	case DIGIT0 : this.update(0);
        		break;
        	case NUMPAD0 : this.update(0);
    			break;
        	case DIGIT1 : this.update(1);
    			break;
        	case NUMPAD1 : this.update(1);
    			break;
        	case DIGIT2 : this.update(2);
    			break;
        	case NUMPAD2 : this.update(2);
    			break;
        	case DIGIT3 : this.update(3);
    			break;
        	case NUMPAD3 : this.update(3);
    			break;
        	case DIGIT4 : this.update(4);
    			break;
        	case NUMPAD4 : this.update(4);
    			break;
        	case DIGIT5 : this.update(5);
    			break;
        	case NUMPAD5 : this.update(5);
				break;
        	case DIGIT6 : this.update(6);
				break;
        	case NUMPAD6 : this.update(6);
				break;
        	case DIGIT7 : this.update(7);
				break;
        	case NUMPAD7 : this.update(7);
				break;
        	case DIGIT8 : this.update(8);
				break;
        	case NUMPAD8 : this.update(8);
				break;
        	case DIGIT9 : this.update(9);
				break;
        	case NUMPAD9 : this.update(9);
				break;
        	case BACK_SPACE : this.update('C');
				break;
        	case COMMA : this.update('K');
				break;
        	case PERIOD : this.update('K');
				break;
        	case DECIMAL : this.update('K');
				break;
        	case ADD : {
        		this.berechne();
        		letzterOperator = '+';
        	}
    			break;
        	case SUBTRACT : {
        		this.berechne();
        		letzterOperator = '-';
        	}
				break;
        	case MULTIPLY : {
        		this.berechne();
        		letzterOperator = '*';
        	}
				break;
        	case DIVIDE : {
        		this.berechne();
        		letzterOperator = '/';
        	}
				break;
        	case ENTER : {
        		this.berechne();
        		zwischenergebnis = Double.NaN;
        	}
				break;
		default:
			break;
	    }
    }
    
    
    void update(Object i) {
    	
    	if (i instanceof Integer) ausgabePuffer=ausgabePuffer+i.toString();
    				// erweitert den Ausgabepuffer um das zuletzt eingegebene Zeichen
    	if (i instanceof Character) {
    		
    		if (!ausgabePuffer.isEmpty() && ((Character)i).charValue()=='C') {
    			
    			if (kommaFlag && ausgabePuffer.charAt(ausgabePuffer.length()-2)=='.') {
    				
        				ausgabePuffer=ausgabePuffer.substring(0, ausgabePuffer.length()-2);
        				kommaFlag = false;
    			}	// löscht das Komma, wenn man die erste Stelle nach dem Komma durch Drücken der Taste 'C' löscht
    			
    			else ausgabePuffer=ausgabePuffer.substring(0, ausgabePuffer.length()-1);
    				// löscht das zuletzt eingegebene Zeichen
    		}
    		
    		if (ausgabePuffer.isEmpty() && ((Character)i).charValue()=='C') {
    				// löscht alles (Ergebnisanzeige) wenn keine Eingabe vorliegt
    			this.anzeigen("");
    			operand = 0;
    			zwischenergebnis = Double.NaN;
    		}
    		
    		if (((Character)i).charValue()=='K' && !kommaFlag) {
    				// setzt das Komma, wenn man die Taste 'K' zum ersten Mal drückt
    			kommaFlag = true;
    			ausgabePuffer=ausgabePuffer+".";
    		}
    	}
    	
    	if (!ausgabePuffer.isEmpty()) {
    				// übernimmt den Ausgabepuffer in die Anzeige und übernimmt einen Cast nach Double als Operand
    		this.anzeigen(ausgabePuffer);
    		operand = Double.parseDouble(ausgabePuffer);
    	}

    }
    
    
    void berechne() {
    	
    	if (Double.isNaN(zwischenergebnis)) zwischenergebnis = operand;
    				// übernimmt die eingegebene Zahl vor Drücken einer Berechnungstaste als erstes Zwischenergebnis, wenn dies zuvor keinen Wert hatte
    	else {
    				// führt die vier Grundrechenarten aus
	    	if (letzterOperator=='+') zwischenergebnis = zwischenergebnis + operand;
	    	else if (letzterOperator=='-') zwischenergebnis = zwischenergebnis - operand;
	    	else if (letzterOperator=='*') zwischenergebnis = zwischenergebnis * operand;
	    	else if (letzterOperator=='/') zwischenergebnis = zwischenergebnis / operand;
    	}
    	
	    this.anzeigen(zwischenergebnis);
	    operand = zwischenergebnis;
	    ausgabePuffer = "";
	    kommaFlag = false;
	    			// übernimmt das zuletzt berechnete Zwischenergebnis in die Anzeige
    }
    
    
    void anzeigen(Object d) {
    	
    	if (d instanceof String) ausgabe.setText((String)d);
    	if (d instanceof Double) ausgabe.setText(df.format((Double)d));
    				// stellt den Ausgabestring mit bis zu acht Ziffern vor und nach dem Komma (ohne überflüssige Nullen) im Label dar
    }
    
    
	public void start(Stage primaryStage) {
		try {
			URL location = getClass().getResource("UI.fxml");

			FXMLLoader fxmlLoader = new FXMLLoader();
			fxmlLoader.setController(this);			//äquivalent zu fx:controller="Taschenrechner" in fxml-Datei

			Parent root = (Parent) fxmlLoader.load(location.openStream());
			
			Scene scene = new Scene(root);
			scene.setOnKeyPressed(new EventHandler<KeyEvent>()
				      {
		         		public void handle(KeyEvent keyEvent)
		         			{
		         				
		         				tastatureingabeVerarbeiten(keyEvent);
		         			}
		      });
			primaryStage.setScene(scene);
			primaryStage.show();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	
	public static void main(String[] args) {
		launch(args);
	}
}
```


----------



## dzim (1. Jul 2014)

Das einfachste wäre wohl, ein CSS anzugeben und den entsprechenden Bereich umzuschreiben (copy&paste von caspian.css (Java7) oder modena.css (Java8) mal den Bereich zu den Buttons (.button) suchen und da mal schauen - da muss es eine Pseudo-Klasse für haben).


----------

