• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Java - jaki pojemnik na przyciski?

Object Storage Arubacloud
0 głosów
332 wizyt
pytanie zadane 5 kwietnia 2019 w Java przez Krupenz Początkujący (360 p.)

Cześć! Postanowiłem jako pierwszy projekt w Javie (GUI w Swing) napisać sobie prosty kalkulator i mam malutki koncepcyjny problem. Wszystkie przyciski dostępne w kalkulatorze przechowuje w jednym JPanelu i tworzę je tam "na sztywno".

one = new JButton("1");
        two = new JButton("2");
        three = new JButton("3");
        four = new JButton("4");
        five = new JButton("5");
        six = new JButton("6");
        seven = new JButton("7");
        eight = new JButton("8");
        nine = new JButton("9");
        nough = new JButton("0");
        percent = new JButton("%");
        square = new JButton("sqrt");
        power = new JButton("x^2");
        inverse = new JButton("1/x");
        clear_all = new JButton("CE");
        clear_one = new JButton("C");
        backspace = new JButton("<-");
        division = new JButton("/");
        multiplication = new JButton("*");
        substraction = new JButton("-");
        addition = new JButton("+");
        equation = new JButton("=");
        comma = new JButton(",");
        mark_change = new JButton("+/-");
        
        add(percent);
        add(square);
        add(power);
        add(inverse);
        add(clear_all);
        add(clear_one);
        add(backspace);
        add(division);
        add(seven);
        add(eight);
        add(nine);
        add(multiplication);
        add(four);
        add(five);
        add(six);
        add(substraction);
        add(one);
        add(two);
        add(three);
        add(addition);
        add(mark_change);
        add(nough);
        add(comma);
        add(equation);


Chciałbym zrobić to nieco w sprytniejszy sposób, tak żeby operacje powtarzające się dla wszystkich przycisków (stylistyka itp) móc wykonywać w pętli, a każdy element zachował identyfikującą go nazwę. Łatwiej byłoby mi operować tymi przyciskami później w kodzie (co raczej by się nie udało jeśli stworzyłbym sobie tablicę buttonów). Czy przychodzi wam do głowy jakiś fajny sposób który rozwiązałby mój problem?

2 odpowiedzi

0 głosów
odpowiedź 5 kwietnia 2019 przez mbabane Szeryf (79,280 p.)

Na przykład dwie tablice, jedna z etykietami, druga z faktycznym buttonem. Zredukujesz to wtedy prawdopodobnie do około 5 linii.

I jak coś to 

nie tak:

mark_change

tylko tak:

markChange

 

komentarz 5 kwietnia 2019 przez Krupenz Początkujący (360 p.)

Dzięki za wskazówkę.

Nie potrafię odszukać użyteczności w tym rozwiązaniu. Chcąc się odwołać do przycisku percent mam najpierw odszukać jego index przeszukując tablicę z nazwami, aby potem użyć tego indeksu do odwołania się do obiektu? trochę sporo z tym roboty :>

Z drugiej strony może nie będe się odwoływał do tych przycisków zbyt często, jedynie wpisywał instrukcje do actionListenera...

Właśnie wpadłem na pomysł aby indeksy tablicy ustalić za pomocą ENUMa, myślisz, że to lepsze rozwiązanie?

komentarz 5 kwietnia 2019 przez mbabane Szeryf (79,280 p.)

Bardziej miałem na myśli ten konkretny przypadek z tworzeniem buttonów, bo można wtedy zrobić tak:

JButton [] buttons = new JButton[4];
String [] buttonLabels = {"1", "2", "3", "4"};

for (int i = 0; i < buttons.length; i++) {
            buttons[i] = new JButton(buttonLabels[i]);
            jPanel.add(buttons[i]);
}

Z dodaniem akcji do przycisków numerycznych prawdopodobnie możesz jakoś też wykorzystać tabelę buttons. Z plusem, minusem itp chyba też będzie się tak dało. Z buttonem +/- trzeba chyba zrobić coś innego bo to specyficzny wydaje mi się przypadek i tam będzie inna logika. Z resztą buttonow tj. sqrt itp. chyba trzeba będzie jakoś indywidualnie to rozwiązać.

Może póki co uprość sobie ten kalkulator do standardowego plus minus, mnożenie i dzielenie. Bo te SQRT i inne mogą Ci wprowadzić trochę zamieszania. A jak się tym uporasz to jako rozszerzenie dodasz sobie nowy "ficzer" np SQRT.

0 głosów
odpowiedź 6 kwietnia 2019 przez Hexatorn Bywalec (2,240 p.)

Moim zdaniem takim kontenerem na przyciski jest właśnie JPanel. A kod który pokazałeś jest inicjowaniem zawartości tego kontenera.
Chyba pytasz o coś takiego, przykład z internetu.

Component[] components = panel.getComponents();
	for (int i = 0; i < components.length; i++) {
		int currXMax = components[i].getX() + components[i].getWidth();
		int currYMax = components[i].getY() + components[i].getHeight();
		if (currXMax > maxX) maxX = currXMax;
		if (currYMax > maxY) maxY = currYMax;
	}

tu więcej przykładów.

Poza tym polecam JavaFX zamiast Swinga.

Przyciski na oknie tworzysz w graficznym edytorze, ustalasz tam ich rozmieszczenie i wygląd. GUI które wyklinasz jest potem zapisywane jako plik .fxml. A w samym kodzie Javy podpinasz tylko to co ma robić przycisk + ewentualne bardziej zaawansowane rzeczy z GUI.

JavaFX daje większe możliwość, zmniejsza ilość kodu i lepiej wygląda od GUI stworzonego w Swinga. A jakbyś chciał poszaleć z wyglądem to możesz to tego dołożyć style CSS.

tu video tutorial JavaFX
Jakbyś miał jakieś problemy jak zacząć z JavaFX to pytaj śmiało.

komentarz 6 kwietnia 2019 przez Hexatorn Bywalec (2,240 p.)

! Uwaga Spoiler !

A tu jak by to mniej więcej wyglądało w FavaFX, kod czasem wywala błędy gdy próbuje odczytać pustą wartość z pola tekstowego. Oczywiście polecam napisanie samemu.

Lecz chodziło o przedstawienie idei.
 

 

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {
    public Main() {
    }

    public void start(Stage primaryStage) throws Exception {
        Parent root = (Parent)FXMLLoader.load(this.getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300.0D, 275.0D));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Controler
 

package sample;

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;


public class Controller {
    @FXML
    Button btn_1;
    @FXML
    Button btn_2;
    @FXML
    Button btn_3;
    @FXML
    Button btn_4;
    @FXML
    Button btn_5;
    @FXML
    Button btn_6;
    @FXML
    Button btn_7;
    @FXML
    Button btn_8;
    @FXML
    Button btn_9;
    @FXML
    Button btn_plus;
    @FXML
    Button btn_minus;
    @FXML
    Button btn_equal;
    @FXML
    Button btn_clear;
    @FXML
    TextField tf_score;

    private int memory = 0;
    private char operation =' ';
    boolean clearScore = false;

    @FXML
    private void initialize(){
        btn_1.setOnAction(event -> handleNumberbuton(1));
        btn_2.setOnAction(event -> handleNumberbuton(2));
        btn_3.setOnAction(event -> handleNumberbuton(3));
        btn_4.setOnAction(event -> handleNumberbuton(4));
        btn_5.setOnAction(event -> handleNumberbuton(5));
        btn_6.setOnAction(event -> handleNumberbuton(6));
        btn_7.setOnAction(event -> handleNumberbuton(7));
        btn_8.setOnAction(event -> handleNumberbuton(8));
        btn_9.setOnAction(event -> handleNumberbuton(9));

        btn_plus.setOnAction(event -> handleOperation('+'));
        btn_minus.setOnAction(event -> handleOperation('-'));

        btn_clear.setOnAction(event -> handleClear());
        btn_equal.setOnAction(event -> handleDoOperation());
    }

    private void handleDoOperation() {
        int value = Integer.parseInt( tf_score.getText());
        switch (operation){
            case '+':
                tf_score.setText(""+(memory+value));
                break;
            case '-':
                tf_score.setText(""+(memory-value));
                break;
        }
    }

    private void handleClear() {
        tf_score.setText("");
        operation = ' ';
        memory = 0;
    }

    private void handleNumberbuton(int number){
        if(clearScore==true){
            memory = Integer.parseInt(tf_score.getText());
            tf_score.setText("");
            clearScore = false;
        }

        tf_score.setText(tf_score.getText()+number);
    }

    private void handleOperation(char c){
       clearScore = true;
       operation = c;
    }
}

FXML
 

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="181.0" prefWidth="185.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
    <children>
        <Button fx:id="btn_clear" layoutX="14.0" layoutY="46.0" mnemonicParsing="false" text="CE" />
        <TextField fx:id="tf_score" layoutX="14.0" layoutY="14.0" prefHeight="25.0" prefWidth="162.0" />
        <Button fx:id="btn_7" layoutX="14.0" layoutY="80.0" mnemonicParsing="false" text="7" />
        <Button fx:id="btn_4" layoutX="14.0" layoutY="114.0" mnemonicParsing="false" text="4" />
        <Button fx:id="btn_1" layoutX="14.0" layoutY="146.0" mnemonicParsing="false" text="1" />
        <Button fx:id="btn_8" layoutX="44.0" layoutY="81.0" mnemonicParsing="false" text="8" />
        <Button fx:id="btn_5" layoutX="44.0" layoutY="115.0" mnemonicParsing="false" text="5" />
        <Button fx:id="btn_2" layoutX="44.0" layoutY="147.0" mnemonicParsing="false" text="2" />
        <Button fx:id="btn_9" layoutX="76.0" layoutY="81.0" mnemonicParsing="false" text="9" />
        <Button fx:id="btn_6" layoutX="76.0" layoutY="115.0" mnemonicParsing="false" text="6" />
        <Button fx:id="btn_3" layoutX="76.0" layoutY="147.0" mnemonicParsing="false" text="3" />
        <Button fx:id="btn_plus" layoutX="114.0" layoutY="147.0" mnemonicParsing="false" text="+" />
        <Button fx:id="btn_minus" layoutX="114.0" layoutY="114.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="25.0" text="-" />
        <Button fx:id="btn_equal" layoutX="147.0" layoutY="146.0" mnemonicParsing="false" text="=" />
    </children>
</AnchorPane>

 

Podobne pytania

0 głosów
0 odpowiedzi 370 wizyt
0 głosów
0 odpowiedzi 234 wizyt
pytanie zadane 12 listopada 2020 w C# przez Masterkk121 Początkujący (280 p.)
0 głosów
1 odpowiedź 135 wizyt
pytanie zadane 1 kwietnia 2020 w C i C++ przez Eriss69 Gaduła (4,470 p.)

92,568 zapytań

141,420 odpowiedzi

319,620 komentarzy

61,954 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...