Java Swing - dodawanie akcji do ekranowej klawiatury

Odpowiedz Nowy wątek
2018-12-23 13:16
0

Witam, jestem w trakcie pisania swojego pierwszego "większego" projektu i nauki SWING'a. Napotkałem problem przy tworzeniu klawiatury ekranowej, a mianowicie wywoływania akcji przycisku. Czy jest jakiś sposób aby masowo (to jest np w pętli) nazwać kilka przycisków? Czy trzeba każdy przycisk klawiatury dodawać, nazywać i przypisywać mu akcję (jeśli naciśniesz przycisk "W" to napisz literkę "W") oddzielnie? Poniżej kod samej klawiatury. Metoda addRowOfKeys dodaje przyciski, ale bez konkretnej nazwy.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JPanel;

public class KeyboardPanel extends JPanel implements ActionListener {
    public final int MAIN_FRAME_WIDTH = 480;
    public final int MAIN_FRAME_HEIGHT = 800;
    String alphabetFirstRow = "QWERTYUIOP";
    String alphabetSecondRow = "ASDFGHJKL";
    String alphabetThirdRow = "ZXCVBNM";

    public KeyboardPanel() {

        setPreferredSize(new Dimension(MAIN_FRAME_WIDTH, (int) (MAIN_FRAME_HEIGHT * 0.4)));
        setLocation(0, MAIN_FRAME_HEIGHT / 2);
        setBackground(Color.DARK_GRAY);

        addKeyboardButtons();

        setVisible(true);

    }

    private void addKeyboardButtons() {
        addRowOfKeys(alphabetFirstRow);
        addRowOfKeys(alphabetSecondRow);
        addRowOfKeys(alphabetThirdRow);
    }

    private void addRowOfKeys(String alphabetRow) {
        JPanel keysPanel = new JPanel(new GridLayout());

        keysPanel.setSize(MAIN_FRAME_WIDTH, (int) (MAIN_FRAME_HEIGHT * 0.10));

        for (int i = 0; i < alphabetRow.length(); i++) {
            String letter = "" + alphabetRow.charAt(i);
            JButton letterButton = new JButton(letter);

            int buttonWidth = (int) (MAIN_FRAME_WIDTH * 0.1);
            int buttonHeight = (int) (MAIN_FRAME_HEIGHT * 0.125);

            letterButton.setMargin(new Insets(-buttonHeight, -buttonWidth, -buttonHeight, -buttonWidth));
            letterButton.setPreferredSize(new Dimension(buttonWidth, buttonHeight));
            letterButton.setFont(new Font("Arial", Font.PLAIN, 20));
            letterButton.addActionListener(this);
            keysPanel.add(letterButton);
        }
        add(keysPanel);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();

        if(source==letterButton(Color.RED));

    }
}

Pozostało 580 znaków

2018-12-23 13:27
0

Zakładam, że naciśnięcie przycisku ma dopisać literę do JTextField o nazwie `tf`` i że nie zwracasz uwagi na wielkość litery.

letterButton.addActionListener(e -> setText(tf.getText() + e.getActionCommand());

Kod się uprości, jeżeli przycisk dopisuje literę do JTextArea.
Kod się skomplikuje, jeżeli przycisk wstawia literę w miejscu gdzie jest kursor i jeżeli od czegoś "zewnętrznego" zależy czy wstawić mała czy dużą literę.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
edytowany 1x, ostatnio: bogdans, 2018-12-23 13:34

Pozostało 580 znaków

2018-12-23 14:15
0

Halo, mamy 2018 rok. Jeżeli jesteś studentem i musisz napisać program w swingu to rozumiem. Jeżeli chcesz pracować w programach napisanych X lat temu w swingu i je utrzymywać to rozumiem. W każdym innym przypadku - wybrałeś sobie złą technologie.

Jeżeli koniecznie chcesz bawić się w okienkowe aplikacje to ogarnij javę 11 + open JX (java FX) - jest to obecnie najnowsza technologia do tworzenia aplikacji okienkowych w javie.
Jeżeli chcesz po prostu tworzyć aplikacje okienkowe to zastanów się nad zmianą języka, bo aplikacje okienkowe w javie to jest nisza, dużo częściej robi się aplikacje okienkowe w C#/C++, niedawno temu powstał też elektron JS, w którym można tworzyć aplikacje desktopowe w html/css/js

Pozostało 580 znaków

2018-12-23 14:36
0
bogdans napisał(a):

Zakładam, że naciśnięcie przycisku ma dopisać literę do JTextField o nazwie `tf`` i że nie zwracasz uwagi na wielkość litery.

letterButton.addActionListener(e -> setText(tf.getText() + e.getActionCommand());

Kod się uprości, jeżeli przycisk dopisuje literę do JTextArea.
Kod się skomplikuje, jeżeli przycisk wstawia literę w miejscu gdzie jest kursor i jeżeli od czegoś "zewnętrznego" zależy czy wstawić mała czy dużą literę.

Nie sprecyzowałem. Ogólnie jest to projekt "wisielca". Klawiatura miała dawać literkę w postaci zmiennej string/char, którą potem będę mógł sprawdzić czy występuje w słowie, czy nie.

Chyba ogarniam co to robi twój kawałek kodu, ale hmm, nie wiem gdzie i jak powinno się to wpleść. Wymyśliłem coś takiego, niestety próba wypisania litery w konsoli kończy się wpisaniem literki do przycisku xD Poniżej skrócony kod i pogrubiony zmiany w nim

    private void addKeyboardButtons() {
        addRowOfKeys(alphabetFirstRow);
        addRowOfKeys(alphabetSecondRow);
        addRowOfKeys(alphabetThirdRow);
    }

    private void addRowOfKeys(String alphabetRow) {
        JPanel keysPanel = new JPanel(new GridLayout());

        keysPanel.setSize(MAIN_FRAME_WIDTH, (int) (MAIN_FRAME_HEIGHT * 0.10));

        for (int i = 0; i < alphabetRow.length(); i++) {
            String letter = "" + alphabetRow.charAt(i);
            JButton letterButton = new JButton(letter);

            int buttonWidth = (int) (MAIN_FRAME_WIDTH * 0.1);
            int buttonHeight = (int) (MAIN_FRAME_HEIGHT * 0.125);

            letterButton.setMargin(new Insets(-buttonHeight, -buttonWidth, -buttonHeight, -buttonWidth));
            letterButton.setPreferredSize(new Dimension(buttonWidth, buttonHeight));
            letterButton.setFont(new Font("Arial", Font.PLAIN, 20));

//od tego momentu pojawiają się zmiany

            letterButton.addActionListener(e -> letterButton.setText(letterButton.getText() + e.getActionCommand()));
        keysPanel.add(letterButton);
        }
        add(keysPanel);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();
        String alphabet="QWERTYUIOPASDFGHJKLZXCVBNM";

        for(int i=0; 0<alphabet.length(); i++) {
            String alphabetLetter = "" + alphabet.charAt(i);
            if(source==alphabetLetter) {
                System.out.println(alphabetLetter);
            }
        }
    }

Pozostało 580 znaków

2018-12-23 16:04
0

To zrób tak:

private void getLetter(ActionEvent ae)
{
     String letter = ae.getActionCommand();
     if(word.contains(letter))
     ...
}
...
letterButton.addActionListener(e -> getLetter());

To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell

Pozostało 580 znaków

2018-12-25 20:50
0
bogdans napisał(a):

To zrób tak:

private void getLetter(ActionEvent ae)
{
     String letter = ae.getActionCommand();
     if(word.contains(letter))
     ...
}
...
letterButton.addActionListener(e -> getLetter());

Super! Dzięki, rozwiązanie które mnie satysfakcjonuje okazało się prostsze niż myślałem

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0