PDA

View Full Version : [Java/Swing] casella di controllo


TuLKaS85
21-02-2007, 16:53
salve, devo realizzare una casella che in base allo stato di alcune variabili si comporti in un determinato modo....

esempio :
se variabile >20 casella verde
se 10< variabile <20 casella gialla
se variabile =0 casella rossa

ovviamente saprei realizzare la cosa in seguito ad un evento definito, ma le caselle si dovrebbero modificare automaticamente in base allo stato della variabile ... si può fare ??

TuLKaS85
23-02-2007, 18:50
:confused:

^TiGeRShArK^
23-02-2007, 19:07
:confused:

che intendi x casella? :fagiano:
tipo nel caso di una JTextField devi fare così:

JTextField field = new JTextField();
JTextField field1 = new JTextField();
field.setBackground(new Color(255,0,0,255)); //RED
field1.setBackground(new Color(0,255,0,255)); //GREEN

TuLKaS85
23-02-2007, 23:57
che intendi x casella? :fagiano:
tipo nel caso di una JTextField devi fare così:

JTextField field = new JTextField();
JTextField field1 = new JTextField();
field.setBackground(new Color(255,0,0,255)); //RED
field1.setBackground(new Color(0,255,0,255)); //GREEN


si una cosa del genere... a me bastava anche un quadratino con sfondo colorato...

il problema è colorare in seguito ad un determinato evento... ho letto che esistono gli itemEvent... sarà la risposta che cerco ??

lovaz
24-02-2007, 12:45
Se ti interessa solo il quadratino usa una JLabel,
per l'evento basta che setti il colore nel listener appropriato

PGI-Bis
24-02-2007, 15:20
C'è un problema di divergenza tra la rappresentazione umana delle cose e la loro realtà fisica. I calcolatori ed i linguaggi di programmazione, per quanto pomposamente si tenti di negarlo, adottano un punto di vista fisico nella rappresentazione dello stato delle cose. I dati subiscono l'effetto di qualcosa.

Gli esseri umani adottano al contrario un'interpretazione personificante: i dati fanno qualcosa.

La casa crolla. In realtà la casa non fa un bel niente. Subisce l'effetto di una forza e tale forza altera l'integrità delle sue parti.

La casella cambia colore. In verità la casella non cambia un bel niente. C'è qualcosa che cambia il colore della casella.

La faccenda curiosa è che l'interpretazione attiva, personificante dei fenomeni è possibile ma complicata e inefficiente. E' il sintomo di due malattie: i linguaggi di programmazione non sono fatti perchè l'uomo esprima sè stesso e la legge di Moore è uno slogan valido solo se la questione sia "quanto fa 1 + 1".

La casella che cambia colore quando delle variabili mutino il loro valore è un esempio interessante della questione. L'approccio umano al fenomeno è espresso nella frase stessa. La casella osserva la variabile e quando nota un mutamento di valore cambia il proprio colore. L'approccio più direttamente rappresentabile attraverso un linguaggio di programmazione richiede invece una reinterpretazione passiva. Il colore della casella viene cambiato dalla variabile quando il valore di quest'ultima viene cambiato da qualcun'altro.

Una possibile traduzione in Java dell'interpretazione umana del fenomeno (la casella fa qualcosa quando nota che il valore della variabile cambia) è questa.

/** Valore alterabile nominato */
public interface Variabile {

/** Accesso al valore corrente di
questa variabile */
Object getValore();

/** Impostazione di un nuovo valore per
questa variabile */
void setValore(Object nuovoValore);

/** Accesso al nome della variabile */
String getNome();

/** Questione di accesso concorrente al
valore di una variabile. */
void bloccaAccesso();

/** Questione di accesso concorrente al
valore di una variabile. */
void liberaAccesso();
}

import java.util.concurrent.locks.*;

public class VariabileIntera implements Variabile {
private final Lock SERRATURA_ACCESSO = new ReentrantLock();
private volatile Integer valore = 0;
private final String NOME;

/** Crea una variabile intera con il nome in argomento. Il
valore iniziale di questa variabile è 0 (zero). */
public VariabileIntera(String nome) {
NOME = nome;
}

/** Restituisce il nome di questa variabile. */
public String getNome() {
return NOME;
}

/** Imposta il valore di questa variabile. L'argomento deve essere
un Integer diverso da null. */
public void setValore(Object nuovoValore) {
if(nuovoValore == null || !(nuovoValore instanceof Integer)) {
throw new IllegalArgumentException("il valore deve essere un intero != da null");
}
bloccaAccesso();
try {
valore = (Integer)nuovoValore;
} finally {
liberaAccesso();
}
}

/** Restituisce il valore di questa variabile. */
public Object getValore() {
return valore;
}

/** Blocca l'accesso alla scrittura del valore */
public void bloccaAccesso() {
SERRATURA_ACCESSO.lock();
}

/** Libera l'accesso alla scrittura del valore */
public void liberaAccesso() {
SERRATURA_ACCESSO.unlock();
}
}

import java.util.*;
import java.util.concurrent.locks.*;
import java.util.concurrent.*;
import javax.swing.*;
import java.awt.*;

public class Casella {
private ConcurrentLinkedQueue<Variabile> variabiliOsservate =
new ConcurrentLinkedQueue<Variabile>();
private ConcurrentHashMap<Variabile, Object> mappaValoriPrecedenti =
new ConcurrentHashMap<Variabile, Object>();
private volatile Thread esecutore;
private final JLabel COMPONENTE;

/** Un oggetto che cambia colore quando cambia il valore delle
variabili che osserva. */
public Casella() {
COMPONENTE = new JLabel();
COMPONENTE.setOpaque(true);
COMPONENTE.setBorder(BorderFactory.createLineBorder(Color.BLACK));s
Dimension size = new Dimension(24, 24);
COMPONENTE.setPreferredSize(size);
COMPONENTE.setMinimumSize(size);
COMPONENTE.setPreferredSize(size);
esecutore = new Thread(osservazione);
esecutore.setDaemon(true);
esecutore.start();
}

/** Restituisce il componente Swing che rappresenta
graficamente questa Casella */
public JComponent getComponente() {
return COMPONENTE;
}

/** Aggiunge alla casella una variabile da osservare. */
public void aggiungiVariabileDaOsservare(Variabile v) {
mappaValoriPrecedenti.put(v, v.getValore());
variabiliOsservate.add(v);
}

/** Sottrae alla casella una delle variabile che osserva */
public void rimuoviVariabileOsservata(Variabile v) {
mappaValoriPrecedenti.remove(v);
variabiliOsservate.remove(v);
}

/** Questioni tecniche */
public void libera() {
final Thread cache = esecutore;
if(cache != null) {
cache.interrupt();
}
}

/** Questioni tecniche */
private Runnable osservazione = new Runnable() {
public void run() {
try {
while(true) {
rilevaMutazioniDiValore();
}
} catch(InterruptedException ex) {
System.out.println("Osservazione interrotta");
}
}
};

/** La casella cerca di capire se il valore di una delle variabili
che osserva sia cambiato */
private void rilevaMutazioniDiValore() throws InterruptedException {
for(Variabile variabile : variabiliOsservate) {
try {
variabile.bloccaAccesso();
Object vecchioValore = mappaValoriPrecedenti.get(variabile);
Object valoreCorrente = variabile.getValore();
if(valoreCorrente.equals(vecchioValore) == false) {
mappaValoriPrecedenti.put(variabile, valoreCorrente);
aggiornaStato(variabile);
}
} finally {
variabile.liberaAccesso();
}
}
Thread.sleep(10);
}

/** Cambia il colore della casella in base al valore della
variabile */
private void aggiornaStato(Variabile v) {
Object valore = v.getValore();
if(valore != null && valore instanceof Integer) {
Integer numero = (Integer)valore;
if(numero > 20) {
impostaColore(Color.GREEN);
} else if(numero > 10) {
impostaColore(Color.YELLOW);
} else if(numero == 0) {
impostaColore(Color.RED);
}
}
}

/** Questioni tecniche */
private void impostaColore(final Color COLORE) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
COMPONENTE.setBackground(COLORE);
}
});
}
}

Per mettere insieme la faccenda potremmo usare questo Main

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

public class Main implements Runnable {
public static void main(String[] args) {
Main main = new Main();
SwingUtilities.invokeLater(main);
main.avviaScanner();
}

private final Variabile PESO = new VariabileIntera("peso");

public void run() {
Casella casella = new Casella();
casella.aggiungiVariabileDaOsservare(PESO);
JFrame frame = new JFrame("Esempio");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add(casella.getComponente());
frame.pack();
frame.setVisible(true);
}

private void avviaScanner() {
try {
System.out.println("inserire un valore intero per la variabile");
Scanner scanner = new Scanner(System.in);
while(scanner.hasNextLine()) {
String line = scanner.nextLine();
if(line.equals("quit")) {
System.exit(0); //BRUTALONE!
} else {
Integer value = parseInteger(line);
if(value != null) {
PESO.setValore(value);
}
}
}
} catch(Exception ex) {
return;
}
}

private Integer parseInteger(String line) {
try {
return Integer.parseInt(line);
} catch(NumberFormatException ex) {
return null;
}
}
}

Casella è un agente autonomo. Tutto quel che serve perchè esegua il suo compito è che gli sia fornita una variabile da osservare:

Casella casella = new Casella();
casella.aggiungiVariabileDaOsservare(unaVariabile);

Il resto accade perchè Casella "fa" qualcosa.

Occhio invece all'interpretazione non umana. Io dico che la casella cambia colore ma scrivo un'altra cosa: scrivo che la variabile fa cambiare il colore della casella.

public interface Variabile {
void aggiungiOsservatore(OsservatoreVariabile o);

void rimuoviOsservatore(OsservatoreVariabile o);

String getNome();

Object getValore();

void setValore(Object nuovoValore);
}

public interface OsservatoreVariabile {

void osservaMutazioneValoreVariabile(
Variabile variabile,
Object vecchioValore,
Object nuovoValore);
}

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

public class Casella implements OsservatoreVariabile {
private JLabel componente = new JLabel();

public Casella() {
componente.setOpaque(true);
componente.setBorder(BorderFactory.createLineBorder(Color.BLACK));
Dimension size = new Dimension(24, 24);
componente.setMinimumSize(size);
componente.setPreferredSize(size);
componente.setPreferredSize(size);
}

public JComponent getComponente() {
return componente;
}

public void osservaMutazioneValoreVariabile(
Variabile variabile,
Object vecchioValore,
Object nuovoValore)
{
if(nuovoValore != null && nuovoValore instanceof Integer) {
Integer intero = (Integer)nuovoValore;
if(intero > 20) {
componente.setBackground(Color.GREEN);
} else if(intero > 10) {
componente.setBackground(Color.YELLOW);
} else if(intero == 0) {
componente.setBackground(Color.RED);
}
}
}
}

import java.util.*;

public class VariabileIntera implements Variabile {
private List<OsservatoreVariabile> osservatori =
Collections.synchronizedList(
new LinkedList<OsservatoreVariabile>());
private final String NOME;
private Integer valore = 0;

public VariabileIntera(String nomeVariabile) {
NOME = nomeVariabile;
}

public String getNome() {
return NOME;
}

public void aggiungiOsservatore(OsservatoreVariabile o) {
osservatori.add(o);
}

public void rimuoviOsservatore(OsservatoreVariabile o) {
osservatori.remove(o);
}

public void setValore(Object nuovoValore) {
if(nuovoValore != null && nuovoValore instanceof Integer) {
Integer vecchioValore = valore;
valore = (Integer)nuovoValore;
notificaMutazioneValore(vecchioValore, valore);
} else {
throw new IllegalArgumentException("Integer required");
}
}

public Integer getValore() {
return valore;
}

private void notificaMutazioneValore(
Integer vecchioValore, Integer nuovoValore)
{
ArrayList<OsservatoreVariabile> listaOsservatori =
new ArrayList<OsservatoreVariabile>(osservatori);
for(OsservatoreVariabile v : listaOsservatori) {
v.osservaMutazioneValoreVariabile(
this, vecchioValore, nuovoValore);
}
}
}

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

public class Main implements Runnable {
public static void main(String[] args) {
Main main = new Main();
SwingUtilities.invokeLater(main);
main.avviaScanner();
}

private final Variabile PESO = new VariabileIntera("peso");

public void run() {
Casella casella = new Casella();
PESO.aggiungiOsservatore(casella);
JFrame frame = new JFrame("Esempio");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add(casella.getComponente());
frame.pack();
frame.setVisible(true);
}

private void avviaScanner() {
try {
System.out.println("inserire un valore intero per la variabile");
Scanner scanner = new Scanner(System.in);
while(scanner.hasNextLine()) {
String line = scanner.nextLine();
if(line.equals("quit")) {
System.exit(0); //BRUTALONE!
} else {
Integer value = parseInteger(line);
if(value != null) {
PESO.setValore(value);
}
}
}
} catch(Exception ex) {
return;
}
}

private Integer parseInteger(String line) {
try {
return Integer.parseInt(line);
} catch(NumberFormatException ex) {
return null;
}
}
}

Funziona in entrambi i casi ma la seconda rappresentazione è migliore per il calcolatore e richiede meno strumenti Java.

L'unico problema è che la prima versione è quella che voglio io, la seconda è quella che vogliono Java e il calcolatore.

Che andrebbe anche bene se non fosse per una quisquilia: non è il calcolatore che ha inventato l'uomo ma l'uomo il calcolatore.

A scanso di equivoci, non è una mia personale paranoia. Era, anzi, una questione centrale nella teoria della programmazione orientata agli aspetti, prima che arrivassero i teorici dei tipi e la facessero diventare una cosa incomprensibile :D.

TuLKaS85
25-02-2007, 08:17
vi ringrazio...

in effetti è quello che dicevo io, la casella cambia colore in funzione di una variabile, mi trovo completamente daccordo...
:) :)