View Full Version : ScrollBar in Java
Salve a tutti. Vi devo chiedere una cosa veloce: perchè la scrollbar che creo in un frame con questo codice non ha effetto sulla JTextArea associata?
Ecco il codice:
public class GiocoFrame extends JFrame {
private JScrollPane scroller;
public JTextArea testo;
private Container c;
public JPanel panel;
public GiocoFrame() {
this.setSize(350, 400);
this.setTitle("Gioco della sedia");
panel = new JPanel(new FlowLayout());
c = getContentPane();
testo = new JTextArea(17, 20);
scroller = new JScrollPane(testo, scroller.VERTICAL_SCROLLBAR_ALWAYS,
scroller.HORIZONTAL_SCROLLBAR_NEVER);
c.add(scroller,BorderLayout.CENTER);
testo.setCaretPosition(testo.getHeight());
panel.add(testo);
Dimension d = new Dimension(20, 100);
scroller.setPreferredSize(d);
panel.add(scroller);
c.add(panel);
this.setVisible(true);
}
}
sottovento
07-04-2006, 06:30
Come mai hai aggiunto la JTextArea "testo" sia alla JScrollPane sia al panel "panel"? Idem per scroller?
Grazie mille. Il tuo consiglio mi ha risolto il problema e fatto in modo di finire il lavoro entro il tempo necessario per poter andare a seguire un Corso all'Università che altrimenti non avrei potuto seguire per terminare l'elaborato.
Grazie ancora.
Scusa la domanda:m a sei programmatore esperto in JAva, visto che ogni discussione che apro in questa sezione mi rispondi sempre tu. Grazie.
Ora vorrei aggiungere tre campi di input e un pulsante. Ma il frame visualizzato non mi fa vedere niente. Non capisco perchè. Ecco il codice.
//Impostazioni generali del frame
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension dim = kit.getScreenSize();
int altezza = (int)dim.getHeight();
int larghezza = (int)dim.getWidth();
this.setSize(altezza/2, larghezza/2);
this.setTitle("Gioco della sedia");
this.setLocation(100,100);
//Creo pannello e contenitore
panel = new JPanel(new BorderLayout());
c = getContentPane();
//Creo area di testo
testo = new JTextArea(50, 700);
testo.setEditable(false);
//Creo lo scrollatore
scrolla = new JScrollPane(testo,
scrolla.VERTICAL_SCROLLBAR_ALWAYS,
scrolla.HORIZONTAL_SCROLLBAR_NEVER);
Dimension d = new Dimension(900, 700);
scrolla.setPreferredSize(d);
setContentPane(scrolla);
panel.add(scrolla,BorderLayout.CENTER);
//Creo e aggiungo etichette, ricavando il contenuto
JLabel labelSessioni = new JLabel("\n\nNumero di Sessioni");
panel.add(labelSessioni);
campoSessioni = new JTextField(5);
panel.add(campoSessioni);
JLabel labelPersone = new JLabel("\nNumero di Partecipanti");
panel.add(labelPersone);
campoPersone = new JTextField(5);
panel.add(campoPersone);
JLabel labelSedie = new JLabel("\nNumero di Sedie\n");
panel.add(labelSedie);
campoSedie = new JTextField(5);
panel.add(campoSedie);
//Creo il bottone e lo aggiungo
button = new JButton("\nOK");
/*button.addActionListener(this);*/
c.add(button);
c.add(panel);
this.setVisible(true);
this.show();
sottovento
10-04-2006, 14:29
Ciao,
l'istruzione
panel.add(labelSessioni);
aggiungera' la label labelSessioni al pannello. Siccome il pannello ha come gestore di layout BorderLayout, per default finira' in centro, rimpiazzando i controlli che c'erano prima.
La stessa cosa vale per le istruzioni
c.add(button);
c.add(panel);
Siccome hai ricavato c come
c = getContentPane();
succedera' lo stesso gioco di prima.
In questi casi, occorre ripensare alla disposizione che vuoi dare agli oggetti della tua finestra.
Ricorda che non c'e' problema ad usare pannelli all'interno di altri pannelli, creando cosi' la struttura che ti interessa.
Per esempio, non so esattamente cosa devi fare, ma e' probabile che il bottone lo volessi sistemare in fondo allo schermo. Potresti creare un nuovo pannello, mantenere il layout di default (FlowLayout) ed aggiungere questo componente al pannello di partenza, nella parte a sud (BorderLayout.SOUTH).
Questo e' l'aspetto che hanno il 90% dei dialoghi...
Per quanto riguarda il sottoscritto: non penso di essere cosi' esperto. C'e' sempre da imparare.
Il mio lavoro e' nel campo dell'informatica, anche se dal nickname avrai capito che sono un pilota d'aereo (solo PPL, purtroppo :( ). Cmq sono laureato in informatica, e mi occupo di automazione di grossi impianti siderurgici.
High Flying
Sottovento
Ora ho questo problema. Devo creare un Timer e lo faccio cosi:
ScandisceSecondi s= new ScandisceSecondi(secondi, frame, tempo);
this.tempo = new Timer(1000,s);
Questa è la classe che implementa ActionListener:
import java.awt.event.ActionEvent;
import javax.swing.Timer;
public class ScandisceSecondi implements ActionListener{
public int secondi;
public GiocoFrame frame;
Timer tempo;
public ScandisceSecondi(int s, GiocoFrame f, Timer t){
secondi = s;
frame=f;
tempo=t;
}
public void actionPerformed(ActionEvent event) {
if (secondi > 0) {
frame.testo.append("\n\tMancano " + secondi
+ " secondi al via...\n");
}
if (secondi == 0) {
frame.testo.append("\t\tVIA!\n");
tempo.stop();
}
secondi--;
}
}
Purtroppo mi da errore e precisamente questo:
cannot find symbol constructor Timer(int, ScandisceSecondi).
PS: ho risolto il problema del messaggio precedente.
Poi non capisco perchè se, creando un Timer, lo creo cosi:
Timer chiusuraFrame = new Timer(10000, new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
frame.dispose();
}
});
Perchè mi da questo errore?
cannot fin symbol constructor Timer(int,<anonymous ActionListener>)
Il compilatore riconosce un java.util.Timer ma il costruttore che usi denota l'intenzione di avvalersi di un javax.swing.Timer. Usa il nome pienamente qualificato:
javax.swing.Timer chiusuraFrame = new javax.swing.Timer(int ...eccetera);
o correggi le dichiarazioni di importazione.
Io ho gia importato "javax.swing.Timer". Ma nonostante questo ho apportato comunque la tua modifica. E l'errore me lo da sempre.
Mi pare che si possa essere d'accordo sul fatto che la classe javax.swing.Timer effettivamente abbia un costruttore (int, java.awt.event.ActionListener).
La tua classe anonima figlia di ActionListener è inoltre ineccepibilmente esatta.
Prova a sotituire quella porzione di codice con un'indagine riflessiva sul tipo javax.swing.Timer:
for(Constructor c : javax.swing.Timer.class.getConstructors()) {
System.out.println(c);
}
Se compare il costruttore:
public javax.swing.Timer(int,java.awt.event.ActionListener)
ci vuole l'esorcista.
E si. Il costruttore è quello.
Perchè da questo errore?
Puoi incollare il codice completo della classe che contiene quella dichiarazione? Così provo a compilarlo, magari è un bug di javac. Ho provato a curiosare nella bugparade di Sun ma non ho trovato nulla di aperto al riguardo.
Il messaggio del compilatore significa che per lui non esiste un costruttore Timer(int, ActionListener), sebbene il test riflessivo dimostri che invece quel costruttore esiste ed è pienamente accessibile (come deve essere).
sottovento
11-04-2006, 06:47
ci vuole l'esorcista.
Ho provato a replicare l'errore in questione (copiando la linea di codice data), senza successo.
Comincio a pensare anch'io ad un buon esorcista :)
Cmq, se e' possibile vedere il codice che genera questo errore...
High Flying
Sottovento
Ecco il codice:
import java.awt.event.ActionEvent;
import javax.swing.Timer;
public class avviaSessione extends Thread implements ActionListener{
public int numSedie, numPersone, numSessioni, numSessione, secondi;
Timer tempo, chiusuraFrame;
GiocoFrame frame = new GiocoFrame();
public int[] arrayPunteggio;
public String[] arrayPersone;
public Sedia[] arraySedie;
private boolean fineSessione;
Thread t=null;
public int numThread;
public avviaSessione(int numSec,int sedie, int persone, int sessioni, int sessione){
this.numSedie=sedie;
this.numPersone=persone;
this.numSessioni=sessioni;
this.numSessione=sessione;
this.secondi=numSec;
// creazione Timer per il conto alla rovescia
ScandisceSecondi s= new ScandisceSecondi(secondi, frame, tempo);
this.tempo = new Timer(1000,s);
// attende 10 secondi dalla fine e chiude il frame
javax.swing.Timer chiusuraFrame = new javax.swing.Timer(10000, new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
frame.dispose();
}
});
// inizializza l'array punteggio
arrayPunteggio = new int[numPersone];
for (int i = 0; i < numPersone; i++)
arrayPunteggio[i] = 0;
// inizializza l'array persone
arrayPersone = new String[numPersone];
for (int i = 0; i < numPersone; i++)
arrayPersone[i] = "persona" + i;
// inizializza l'array sedie
arraySedie = new Sedia[numSedie];
for (int i = 0; i < numSedie; i++)
arraySedie[i] = new Sedia("sedia" + i);
setFine(false);
Thread t = null;
}
public void actionPerformed(ActionEvent event){
azzeraNumThread();
frame.testo.append("\n\t---------- SESSIONE " + numSessione + " ----------\n");
/*this.secondi = numSec;*/
tempo.start();
while (tempo.isRunning()) {
}
// avvia i thread per ogni sessione
for (int i = 0; i < numPersone; i++) {
t = new Thread(this);
t.setName(Integer.toString(i));
t.start();
}
setFine(true);
while (isFine() == true) {
}
// libera le sedia a fine sessione
for (int i = 0; i < numSedie; i++)
arraySedie[i].libera();
if(numSessione==numSessioni){
frame.testo.append("\n\n\t_________FINE GIOCO_________");
chiusuraFrame.start();
}
}
// restituisce il numero di thread
public synchronized int getNumThread() {
return numThread;
}
// setta il numero di thread
public synchronized void setNumThread() {
this.numThread++;
}
// restituisce il nome contenuto nell'array persone
public synchronized String getNomePersona() {
return arrayPersone[getNumThread()];
}
// azzera il numero di thread attivi
public synchronized void azzeraNumThread() {
this.numThread = 0;
}
// setta il flag di fine gioco
public synchronized void setFine(boolean fineSessione) {
this.fineSessione = fineSessione;
}
// restituisce il valore del flag di fine gioco
public synchronized boolean isFine() {
return fineSessione;
}
}
IO compilo con JCreator.
sottovento
11-04-2006, 10:14
Ciao,
mancano dei pezzi del codice (per es, class Sedia), per cui non ho provato a compilare.
Comunque sembra che non importi java.awt.event.ActionListener. In tal caso, pero', il messaggio di errore dovrebbe essere diverso.
Prova ad importare e fai sapere
High Flying
Sottovento
Ora non sto a casa. Proverò stasera.
Ciao.
E' come dice sottovento. Il messaggio del compilatore è corretto, riconosce un tipo di nome ActionListener che incidentalmente è lo stesso dell'ActionListener del package java.awt.event ma, non essendo stato importato il package o il tipo in questione, non corrisponde a quello richiesto dal costruttore di javax.swing.Timer.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.