PDA

View Full Version : [JAVA] Esempi su KeyListener


franksisca
17-03-2006, 17:21
ragazzi, oltre a questo http://java.sun.com/docs/books/tutorial/uiswing/events/keylistener.html e a questo http://java.sun.com/docs/books/tutorial/uiswing/events/example-swing/KeyEventDemo.java , avete per caso altri esempi pratici su come funziona questa interfaccia???

franksisca
18-03-2006, 15:18
up

PGI-Bis
18-03-2006, 15:48
Ti dirò, io di libri su Java me ne sono letti un tot e li ho trovati tutti strettamente in linea con quanto indicato nel tutorial di Sun.

Mi stupirei se esistesse qualcosa di più. KeyListener è una delle molte forme del pattern listener incluse in AWT/Swing. In sè, non fa nulla più di quanto è mostrato in quel codice d'esempio.

Anzi, in verià non fa neanche quello :eek: . Il funzionamento concreto è altrove (EventQueue e AWTEventMulticaster) ma, dal punto di vista di noi "utenti" AWT/Swing, è quasi un dettaglio.

Ciao.

Pierluigi.

franksisca
18-03-2006, 16:45
ma tu hai mai fatto qualcosa, se si potresti postarla per farmi rendere conto.

PGI-Bis
18-03-2006, 17:09
Questo è un pezzo di un esperimento di un pezzo di un editor XML. Tradotto, è niente di niente :D.

package it.tukano.xml;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;

public class XMLEditor extends JComponent implements KeyListener {
private int caretPosition;
private ArticleNode root = new ArticleNode();
private NodeView rootView = new ArticleView();
private RenderInfo editorInfo = new RenderInfo();

public XMLEditor() {
setFocusable(true);
addKeyListener(this);
PCData data = new PCData();
TitleNode node = new TitleNode();
node.children().add(data);
data.setParent(node);
root.insert(node, 0);
}

public void save() {
System.out.println(root);
}

public PCData getTextElement(IntRef offsetHolder) {
ArrayList<XMLNode> buffer = new ArrayList<XMLNode>();
buffer.addAll(root.children());
PCData target = null;
int textLen = 0;
for(int i = 0; i < buffer.size(); i++) {
XMLNode n = buffer.get(i);
if(n.getName() == Tags.PCDATA) {
if(caretPosition == 0) return (PCData)n;
int len = n.toString().length();
if(caretPosition >= textLen && caretPosition <= textLen + len) {
target = (PCData)n;
offsetHolder.value = caretPosition - textLen;
break;
}
textLen += len;
} else {
buffer.addAll(n.children());
}
}
return target;
}

public void insert(XMLNode newNode) {
IntRef off = new IntRef();
PCData target = getTextElement(off);
target.insert(newNode, off.value);
caretPosition++;
repaint();
}

public void keyTyped(KeyEvent e) {
processCharTyped(e.getKeyChar());
}

public void keyPressed(KeyEvent e) {
processKeyPressed(e.getKeyCode());
}

public void keyReleased(KeyEvent e) {}

private void processCharTyped(char c) {
if(CharUtil.isValidChar(c)) {
if(c == '\t') { System.out.println("tabb"); }
IntRef offset = new IntRef();
PCData node = getTextElement(offset);
node.buffer().insert(offset.value, c);
caretPosition++;
repaint();
} else if(c == '\t') {
System.out.println("tab");
}
}

private void processKeyPressed(int code) {
switch(code) {
case KeyEvent.VK_TAB:
System.out.println("tab");
break;
case KeyEvent.VK_LEFT:
if(caretPosition > 0) caretPosition--;
repaint();
break;
case KeyEvent.VK_RIGHT:
if(caretPosition < editorInfo.textLength) caretPosition++;
repaint();
break;
case KeyEvent.VK_ENTER:
generateNewNode();
break;
case KeyEvent.VK_BACK_SPACE:
removeCharBefore();
break;
case KeyEvent.VK_DELETE:
removeCharAfter();
break;
}
}

public void paintComponent(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());

RenderInfo info = new RenderInfo();
info.graphics = g;
info.x = 0;
info.y = 0;
info.lineWidth = getWidth() - 20;
info.caretPosition = caretPosition;

g.translate(10, 0);
rootView.paint(root, info);
g.translate(-10, 0);

editorInfo = info;
int h = getPreferredSize().height;
if(h != editorInfo.y + 20) {
System.out.println("Reset size");
setPreferredSize(new Dimension(getWidth(), editorInfo.y + 20));
Component parent = this;
while((parent = parent.getParent()) instanceof JViewport == false
&& parent != null) ;
if(parent != null) {
((JViewport)parent).setView(this);
requestFocusInWindow();
}
}
}

private void generateNewNode() {
IntRef offset = new IntRef();
PCData current = getTextElement(offset);
if(current == null) {
throw new RuntimeException("Element is not a text one");
}
TextNode txt = new TextNode();
PCData text = new PCData(" ");
text.setParent(txt);
txt.children().add(text);

current.insert(txt, offset.value);
caretPosition++;
repaint();
}

private void removeCharAfter() {

}

private void removeCharBefore() {
IntRef offset = new IntRef();
PCData current = getTextElement(offset);
if(current == null) throw new RuntimeException("Remove: not PCData");
StringBuilder buffer = current.buffer();
if(buffer.length() == 0 ||
(buffer.length() == 1 && buffer.charAt(0) == ' '))
{
System.out.println("vuoto");
current.getParent().removeFromParent();
caretPosition--;
repaint();
} else {
buffer.deleteCharAt(offset.value - 1);
caretPosition--;
repaint();
}
}
}

Nel costruttore c'è un "addKeyListener" che riconduce all'argomento di questo thread. Il KeyListener nel codice è "this".

keyTyped intercetta gli eventi di digitazione e passa la palla a processCharTyped il cui scopo è iniettare il carattere nel nodo PCData corrente;

keyPressed intercetta gli eventi di pressione e li passa a processKeyPressed che si occupa di gestire i pulsanti di "controllo";

keyRelesed non fa niente

Il tutto funziona insieme ad altre 23 classi che non incollo per pietà :D.

Ciao.

Pierluigi.

franksisca
18-03-2006, 19:23
graie, di tutto, anche della pietà;)