Java Swing - dodawanie akcji do ekranowej klawiatury

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));
		
	}
}
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ę.

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

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);
			}
		}
	}
0

To zrób tak:

private void getLetter(ActionEvent ae)
{
     String letter = ae.getActionCommand();
     if(word.contains(letter))
     ...
}
...
letterButton.addActionListener(e -> getLetter());
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

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