javanewbie Skrevet 9. juni 2005 Del Skrevet 9. juni 2005 Jeg prøvde dette (blandt annet): import javax.swing.*; import java.awt.BorderLayout; /** * Non-modal dialog with indeterminate progress bar */ public class ProgressDialog extends JDialog{ private JProgressBar pb; ProgressDialog(JFrame frame, String sTitle, String sBorder, JLabel label){ super(frame,sTitle,false); pb=new JProgressBar(); pb.setIndeterminate(true); JPanel contentPane = new JPanel(new BorderLayout()); contentPane.add(label,BorderLayout.CENTER); contentPane.add(pb,BorderLayout.CENTER); contentPane.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder(sBorder), BorderFactory.createEmptyBorder(5,5,5,5))); contentPane.setOpaque(true); setContentPane(contentPane); pack(); setLocationRelativeTo(frame); } } //class ProgressDialog Så prøver jeg å bruke den på følgende måte: ProgressDialog dialog=new ProgressDialog(BarDiagramViewer.this,"Vent..","Laster data",new JLabel("Henter data fra database.",new ImageIcon("Images/auto.gif"),JLabel.LEFT)); dialog.setVisible(true); loadData(); //buker lang tid her dialog.setVisible(false); Problemet er at innholdet i panelet contentPane ikke vises! (bare grå bakgrunn). pack() justerer størrelsen på vinduet avhengig av hva jeg putter i panelet.. Hva er det som skjer her? Lenke til kommentar
Drømmemannen Skrevet 12. juni 2005 Del Skrevet 12. juni 2005 Jeg ville prøvd å bytte ut setContentPane(contentPane); med getContentPane().add(contentPane); og kanskje gitt contentPane et annet navn. Lenke til kommentar
javanewbie Skrevet 13. juni 2005 Forfatter Del Skrevet 13. juni 2005 Hvis du mener noe i denne retningen: public class ProgressDialog extends JDialog{ private JProgressBar pb; ProgressDialog(JFrame frame, String sTitle, String sBorder, JLabel label){ super(frame,sTitle,false); pb=new JProgressBar(); pb.setIndeterminate(true); Container c=getContentPane(); JPanel p = new JPanel(new BorderLayout()); p.add(label,BorderLayout.CENTER); p.add(pb,BorderLayout.CENTER); p.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder(sBorder), BorderFactory.createEmptyBorder(5,5,5,5))); p.setOpaque(true); c.add(p); pack(); setLocationRelativeTo(frame); } } //class ProgressDialog ..så har jeg prøvd det også. Samme problem. Lenke til kommentar
Drømmemannen Skrevet 13. juni 2005 Del Skrevet 13. juni 2005 (endret) Har du prøvd å bruke event-dispatching thread? Når det skjer uforklarlige feil med GUIn er det ofte det som må til. Den bør vel egentlig alltid brukes i GUI-sammenheng. Endret 13. juni 2005 av balletryne Lenke til kommentar
javanewbie Skrevet 13. juni 2005 Forfatter Del Skrevet 13. juni 2005 Eh.. Må innrømme at jeg ikke er helt stø på dette -ennå. Jeg har en main: public static void main(String args[]){ //creating and showing this application's GUI. javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { BarDiagramViewer gui=new BarDiagramViewer(); gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JFrame.setDefaultLookAndFeelDecorated(true); } }); } //main() som lager hovedvinduet (JFrame). Prøver senere å kjøre en lengre metode i en checkBoxHandler for et JCheckBoxMenuItem. Det er her jeg vil ha ProgressDialogen på toppen. loadData() metoden laster fra filer og database og tegner resultatet i paneler i BarDiagramViewer frame'n. Antar at det er her problemet oppstår? Burde jeg løst dette på en annen måte? Lenke til kommentar
Drømmemannen Skrevet 13. juni 2005 Del Skrevet 13. juni 2005 Men nå kjører vel loadData også i event-dispatch-tråden? For da blir det jo vanskelig for event-dispatch-tråden å oppdatere innholdet i progressdialogen når disse GUI-endringene blir lagt på slutten av event-køen, dvs at de blir behandlet etter at loadData er ferdig. Eller blir det ikke slik? Har ikke jobbet for mye med dette, men jeg ville skilt fra hverandre oppdatering av og lesing fra GUI fra resten av arbeidet som programmet gjør. Lenke til kommentar
javanewbie Skrevet 13. juni 2005 Forfatter Del Skrevet 13. juni 2005 Du har det i grove trekk, ja.. Vet ikke helt hvordan jeg skal bygge om dette.. Jeg har et antall BarDiagram klasseinstanser (extends JPanel). Hver av disse har sin egen paintComponent(Graphics g) metode som oppdaterer panel når private felter blir oppdatert (setXxx() metoder). Disse panelene eksisterer i BarDiagramViewer klassen under hver sin tab i et JTabbedPane. loadData() metoden i BarDiagramViewer henter data fra filer (planlagt produksjon) og database (realisert produksjon). Disse data legges fortløpende inn i BarDiagrammene vha. setXxx() metoder - dermed oppdateres grafikk etterhvert som dette skjer. Er dette forståelig? Det er mulig at det hele burde gjøres på en helt annen måte. Lenke til kommentar
Drømmemannen Skrevet 13. juni 2005 Del Skrevet 13. juni 2005 (endret) Når trigges loadData? Det går an å starte loadData i egen tråd med referanser til gui-elementene. loadData må da kjøre diagram.setXxx(...); og SwingUtilities.invokeLater(diagram.repaint()); på hvert enkelt diagram som skal oppdateres (eller generalisere det på et vis). Vet ikke hvor fra eller om du kjører repaint, men det som trigger selve omtegningen av vinduet må ihvertfall legges på event-køen. Endret 13. juni 2005 av balletryne Lenke til kommentar
javanewbie Skrevet 13. juni 2005 Forfatter Del Skrevet 13. juni 2005 Prøver senere å kjøre en lengre metode i en checkBoxHandler for et JCheckBoxMenuItem. Det er her jeg vil ha ProgressDialogen på toppen. Det er loadData() jeg snakket om her. Jeg kaller aldri repaint() direkte. Det har det ikke vært behov for tidligere. Får se hva jeg klarer å få til.. Lenke til kommentar
javanewbie Skrevet 13. juni 2005 Forfatter Del Skrevet 13. juni 2005 Dessuten er jeg en xxx løgner! Selvfølgelig kaller jeg repaint() hver gang jeg har lagt nye verdier inn i BarDiagram. Kanskje det finnes en løsning... Lenke til kommentar
Drømmemannen Skrevet 13. juni 2005 Del Skrevet 13. juni 2005 Jeg ville kanskje laget loadData() som run() i en egen klasse som implementerer Runnable og som inneholder pekere til alle diagrammene. Denne vil da også håndtere progressbaren. Og alle metodekall som direkte eller indirekte trigger omtegning av GUI puttes da inn i SwingUtilities.invokeLater() Lenke til kommentar
zulo Skrevet 16. juni 2005 Del Skrevet 16. juni 2005 Prøv å bruk model view controller konseptet eller noe tilnærmet likt, det vil i Java si at du bruker dine egne events. Hvis du f.eks skal oppdatere noe eller gjøre noe arbeid så kan du generere en event og registrere progressbaren som eventlistener på denne eventen. Dette vil føre til at du kan skrive koden som faktisk gjør arbeidet hvor som helst..f.eks i main klassen eller hovedframen, og hvor enn du har jprogressbaren kommer den til å oppdatere seg så lenge den lytter på eventsene dine. Slik gjør jeg det hvertfall. For å lage dine egne events må du ha 2 ting: 1. En klasse som extender java.util.EventObject, kall denne klassen for et eller annet passende f.eks ArbeidsEvent. Du kan la denne eventen inneholde en String eller et tall som forteller jprogressbaren hvor langt arbeidet har kommet..eller andre ting.. 2. En klasse som extender java.util.EventListener; Eksempel: Jeg lager en editor for et spill, jeg har her en klasse jeg kaller EditorManager som inneholder mange DefaultScene objekter. En DefaultScene inneholder blant annet et Image som et bakgrunnsbilde. I GUI skal det da gå an å vise denne scenen ettersom hvilken scene som er valgt. Hvilken scene som er gjeldende holder EditorManager rede på. Da jeg vil presentere scenen i GUI har jeg laget meg et custom JPanel som har fått en referanse til EditorManager gjennom konstruktøren. Den registrerer seg så som en SceneChangedEventListener. Det betyr at EditorManager objektet som har kontroll over hvilke scener som er valgt osv gir beskjed til jpanelet mitt når en annen scene har blitt valgt, og jpanelet kaller da repaint(), som igjen resulterer i at jpanelet tegner seg opp på nytt, og det tegner da alltid opp den scenen som er gjeldende, noe som er enkelt siden den har en referanse til editormanager objektet og kan få tak i gjeldende scene med getCurrentScene metoden som returnere scene objektet som igjen har et bilde osv osv...nå ble det litt uoversiktlig her men. Dette er bare et forslag til hvordan du kan løse gui problemer med gui programmering. Skille ut GUI og "business code". public class ArbeidOppdatertEvent extends EventObject { int stepNr = null; public ArbeidOppdatertEvent(Object source,int stepnr){ super(source); stepNr = stepnr; } //hvis en jprogressbar får denne eventen kan den hente tallet som den kan //bruke //til å vise hvor langt arbeidet har kommet. public int getStepNr(){ return stepNr; } } /* Klassen som skal lytte etter ArbeidOppdatertEvent's implementerer denne klassen. Eksempel: public class jpaneletMitt extends JPanel implements ArbeidOppdatertEventListener{ jprogressbar blabla =fejklpfk...... public jpaneletMitt(){ } public void arbeidOppdatert(ArbeidOppdatertEvent e){ int i = e.getStepNr(); jprogressbar.setEtEllerAnnet(i); } public interface ArbeidOppdatertEventListener extends EventListener{ public void arbeidOppdatert(ArbeidOppdatertEvent evt); } Og så et annet sted i programmet: jpaneletMitt j; addArbeidOppdatertEventListener(j); -gjør en ting -generer en arbeidoppdatertevent og gi den til alle som har registrert seg -gjør neste ting osv osv.. det ble uforståelig sikkert dette her men da har jeg forsøkt hvertfall å si hvordan jeg pleier å gjøre det. Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå