jFrame zamykanie okna + dostęp do innych okien

0

Szanowni forumowicze,
Mam problem z oknem dziedziczącym po JFrame. Otóż mam główne okno programu, a w nim menu. Po wybraniu w menu Opcje->Konfiguracja otwiera mi sie okno z konfiguracją. Po zamknięciu okna "x" w prawym górnym rogu zamyka mi się cała aplikacja. A chciałem zamknąć tylko te okno.
Podejrzewam, że muszę wyłapać zdarzenie na tym "x" i zmienić, żeby w metodzie w tym zdarzeniu nie zamykało mi aplikacji tylko zwalniało samo okno, ale nie wiem gdzie to jest w Swingu(piszę w NetBeans).

A w tym nowym oknie w jaki sposób mogę się odwołać do okna głównego? Szukałem na google, ale na jFrame nic nie znajduję(co prawda jeszcze szukam).

Dziękuję serdecznie,
S.

1

W oknie z konfiguracją zamiast:

 
setDefaultCloseOperation(EXIT_ON_CLOSE);

daj

 
setDefaultCloseOperation(DISPOSE_ON_CLOSE);

W jakim sensie chcesz się odwoływać do okna głównego?

 
private OknoGlowne oknoGlowne;
public OknoKonfiguracji(OknoGlowne oknoGlowne){
     this.oknoGlowne = oknoGlowne;
     oknoGlowne.setVisible(false);
}
0

Dziękuję! O to chodziło:-)

1

Użytkownik będzie zapewne kilkakrotnie otwierał okno konfiguracji. Lepiej zrobić tak:

setDefaultCloseOperation(HIDE_ON_CLOSE);

okno konfiguracji konstruować tylko jeden raz, a w razie potrzeby pokazania tego okna wywoływać

oknoKonfiguracji.setVisible(true);
0

Dzięki. Z visible to nie musi być, bo mam w OknoKonfiguracji event WindowOpen i tam zczytuje konfiguracje, a konf bedzie uzywana raz na ruski rok:-) Ale dzięki za pomysł.

Jednak nie do końca potrafię użyć tych odwołań... Wiem, że to co podałeś jest ok, ale ja jestem noob w JAVA:-)

W oknie głównym tworzę normalnie oknoKonfiguracji i do konstruktora podaje this czyli jFrame aktualnej instancji OknoGlowne:

OknoKonfiguracji oknoKonfiguracji = new OknoKonfiguracji(this);// this to oknoGlowne jak rozumiem

Natomiast w jFrame OknoKonfiguracji(oprócz Twojego kodu) mam takie coś:

public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new Konfiguracja().setVisible(true); // **!!! co tutaj podać?** 
            }
        });

Nie wiem co mam podać do konstruktora, który jest wywoływany w ciele własnej klasy... Te main to musi być? Jakoś nie mogę zapomnieć o prostocie C#:-)

0

OknoKonfiguracji nie potrzebuje metody main(). Konstruktor tego okna możesz wywołać w konstruktorze okna głównego:

private OknoKonfiguracji okno=null;
    ......
okno=new OknoKonfiguracji(this);

(w konstruktorze klasy OknoKonfiguracji nie umieszczaj setVisible(true);).
albo w obsłudze pozycji menu:

if(okno==null)
{
    okno=new OknoKonfiguracji(this);
}
okno.setVisible(true);  
0

Tylko problem jest głębszy. Jak usunę main to mi wywala masę błędów... Nie wiem co z tym zrobić. Po co tworzy się instancja klasy sama w sobie? Nie rozumiem dlaczego tak to jest zrobione.

0

Trudno uwierzyć w to co piszesz, błędy są podczas kompilacji czy podczas uruchamiania?. Pokaż więcej kodu (bez zbędnych szczegółów), gdzie jest entryPoint (metoda main()) zaczynająca aplikację, gdzie i jak są tworzone główne okna (JFrame).

0

Dzięki! O ja głupi! Nie usunąłem jednej klamry, jakoś tak z tyłu była więc nie sprawdzałem do czego należy:-)
Tylko mam teraz problem jak dostać się np. do jText który jest w głównej klasie (forma to w tej głównej klasie jPanel i to jej komponenty mnie interesują).

Ja usunę main to prawie wszystkie linie są na czerwono:D Mogę i wkleić wszystko, ale nie chcę śmiecić, chociaż w tym pliku aż tyle nie ma.
To jest klasa konfiguracja:

    public class Konfiguracja extends javax.swing.JFrame {
    private DelegacjeView mainWindow;  
    /** Creates new form Konfiguracja */
    public Konfiguracja(DelegacjeView mainWindow) {
        this.mainWindow = mainWindow;
        initComponents();
    }


   (...)

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        this.dispose();
    }                                        

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            DelegacjeView oknoGlowne;
            
            public void run() {
                new Konfiguracja(oknoGlowne).setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify                     
    private javax.swing.JButton jButton1;
    (...)
    private javax.swing.JTextField jTextLogin;
    // End of variables declaration                   
}

A teraz trochę pliku DelegacjeView, w którym wywołuję okno konfiguracji:

    private void openConfigFrame(java.awt.event.ActionEvent evt) {                                 
        JFrame configWindow = new Konfiguracja(this);
        configWindow.setVisible(true);
    }  

No i tyle dotyczy się inicjalizacji i wywoływania. Poza tym nie ma nic.

0

Witajcie,
to mój pierwszy post postaram się opisać jak najdokładniej o co mi chodzi, ale jeśli by były jakieś niejasności proszę pytać.
Jako że borykam się z bardzo podobnym problemem co przedmówca, podłączę się pod temat.

Mamy aplikację, która posiada buttona po naciśnięciu którego pojawia się nowe okno z wykresem. Jak zamykam wykres to zamyka mi się nie tylko okno z wykresem ale również cała aplikacja.

<ort> ```java public void pokaz() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //metoda obsługuje zamknięcie głównej aplikacji setVisible(true); setResizable(false);
}
</ort>
```java
 class DualAxis extends ApplicationFrame {

    public DualAxis(final String title) {

        super(title);
    
        final CategoryDataset dataset1 = createDataset1();
        DualAxis.isDefaultLookAndFeelDecorated();
        // tworzymy wykres
        final JFreeChart chart = ChartFactory.createBarChart(
                "Wykres ilości użytkowników w danej minucie", // tytuł wykresu
                "Czas", // domain axis label
                "Ilość użytkowników", // range axis label
                dataset1, // data
                PlotOrientation.HORIZONTAL,
                true, // legenda?
                true, // podpowiedzi?
                false // generator URL?
                );
setDefaultCloseOperation(DualAxis.DISPOSE_ON_Close);                        ///   <---- Tu powinno się ustawiać to, że okno z wykresem zostanie schowane, ale tak nie jest.


        // NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...
        chart.setBackgroundPaint(Color.WHITE);
//        chart.getLegend().setAnchor(Legend.SOUTH);

        // get a reference to the plot for further customisation...
        final CategoryPlot plot = chart.getCategoryPlot();
        plot.setBackgroundPaint(new Color(0xEE, 0xEE, 0xFF));
        plot.setDomainAxisLocation(AxisLocation.BOTTOM_OR_RIGHT);



        final CategoryAxis domainAxis = plot.getDomainAxis();
        domainAxis.setCategoryLabelPositions(CategoryLabelPositions.DOWN_45);
        //final ValueAxis axis2 = new NumberAxis("Secondary");
        // plot.setRangeAxis(1, axis2);

        final LineAndShapeRenderer renderer2 = new LineAndShapeRenderer();
        renderer2.setToolTipGenerator(new StandardCategoryToolTipGenerator());
        plot.setRenderer(1, renderer2);
        plot.setDatasetRenderingOrder(DatasetRenderingOrder.REVERSE);
        // OPTIONAL CUSTOMISATION COMPLETED.

        // dodaje wykres do panelu
        final ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
        setContentPane(chartPanel);

    }

Z Javą dopiero zaczynam programowanie i moja wiedza jest uboga także proszę o wyrozumiałość - jeśli są tu jakieś idiotyczne błędy.

0

Bo już napisał rozwiązanie. Wystarczyło przeczytać.

bo napisał(a)

W oknie z konfiguracją zamiast:
setDefaultCloseOperation(EXIT_ON_CLOSE);
daj
setDefaultCloseOperation(DISPOSE_ON_CLOSE);

0

Bo już napisał rozwiązanie.

bo napisał(a)

W oknie z konfiguracją zamiast:
setDefaultCloseOperation(EXIT_ON_CLOSE);
daj
setDefaultCloseOperation(DISPOSE_ON_CLOSE);

0

A czy Ty w ogóle zajrzałeś do tego kodu co napisałem? Zdaje się, że tam w kodzie jest napisane "DISPOSE_ON_CLOSE". Ja chce by moje okno główne zamykało się po naciśnięciu "x" ale żeby nowe okno, które pojawia się po naciśnięciu buttona przy zamknięciu(tego nowego okna) nie powodowało zamknięcia całej aplikacji.

Proszę czytać ze zrozumieniem, dziękuje.

arrowman napisał(a)

Bo już napisał rozwiązanie.

bo napisał(a)

W oknie z konfiguracją zamiast:
setDefaultCloseOperation(EXIT_ON_CLOSE);
daj
setDefaultCloseOperation(DISPOSE_ON_CLOSE);

0

A ja zajrzałem i nie znalazłem nigdzie DISPOSE_ON_CLOSE. Poza tym dałęś za mało kodu, jakiego typu jest np. AplicationFrame.

0

Tam jest taka komenda z komentarzem :

setDefaultCloseOperation(DualAxis.DISPOSE_ON_Close);                        ///   <---- Tu powinno się ustawiać to, że okno z wykresem zostanie schowane, ale tak nie jest. 

To jest source code ApplicationFrame.

 public class ApplicationFrame extends JFrame implements WindowListener {

    public ApplicationFrame(final String title) {
        super(title);
        addWindowListener(this);
    }
    public void windowClosing(final WindowEvent event) {
        if (event.getWindow() == this) {
            dispose();
            System.exit(0);
        }
    }
    public void windowClosed(final WindowEvent event) {   
    }
    public void windowActivated(final WindowEvent event) {    
    }
    public void windowDeactivated(final WindowEvent event) {   
    }
    public void windowDeiconified(final WindowEvent event) {   
    }
    public void windowIconified(final WindowEvent event) {   
    }
    public void windowOpened(final WindowEvent event) {   
    }

}

Wydaje mi się, że ten fragment może powodować zamykanie aplikacji:

 public void windowClosing(final WindowEvent event) {
        if (event.getWindow() == this) {
            dispose();
            System.exit(0);
        }

Próbowałem zmieniać ten zapis "System.exit(0);" na "System.exit(1);" lub umieszczać go w komentarzu - bez rezultatu.

Pochodzi to z biblioteki jfreechart.

0
System.exit(cokolwiek);

kończy zawsze i nieodwołalnie aplikację.
2.Taki WindowListener jak w klasie AplicationFrame jest niepotrzebny, właściwie jest błędny.
3.Nie znam klasy DualAxis, w szczególności nie wiem co to stała EXIT_ON_Close. Odpowiednie tałe w standardowych klasach Javy nazywają się EXIT_ON_CLOSE - Java jest case-sensitive.

0

Dziękuję Bo za pomoc:-) Dużo nam pomogłeś. I Tobie Brock też. W pierwszym poście rozwiązałeś połowę problemów:-)

Mam jednak jeszcze nie rozwiązany ten problem odwołwywania się w jFrame do komponentów w głównej aplikacji, która ma komponenty w jPanel. Potrafiłbyś dać przykład? Na google znajduje mi nie to co chcę, za długie zapytania.

Dziękuję,
A.

0

Nie rozumiem problemu. W klasie Konfiguracja masz referencję do głównej klasy (mainWindow). Wygeneruj (napisz) gettery w głównej klasie.

//W klasie głównej
public JTextField getPoleTekstowe()
{
   return poleTekstowe;
}
//w klasie Konfiguracja
mainWindow.getPoleTekstowe().setText("dupa");

Komponenty (poleTekstowe) muszą być polami w klasie. Ty zdaje się korzystasz z designera w NB, wtedy każdy komponent jest polem w klasie.

0
bo napisał(a)
System.exit(cokolwiek);

kończy zawsze i nieodwołalnie aplikację.
2.Taki WindowListener jak w klasie AplicationFrame jest niepotrzebny, właściwie jest błędny.
3.Nie znam klasy DualAxis, w szczególności nie wiem co to stała EXIT_ON_Close. Odpowiednie tałe w standardowych klasach Javy nazywają się EXIT_ON_CLOSE - Java jest case-sensitive.

Umieszczałem w komentarzu "System.exit(cokolwiek);" lub nawet usuwałem bez zmian.

  1. To jest biblioteka do rysowania wykresów na razie nie ingeruje w jej strukturę.
  2. Dobrze rozumiem, poprawiłem. Poza tym nie wiem gdzie widzisz "EXIT_ON_Close" było "DISPOSE_ON_Close", które poprawiłem w swoim kodzie - bez zmian.

Całą zawartość klasy "DualAxis" masz podaną tutaj.

0

Jeżeli zamieściłeś na forum "prawdziwy" kod, to aplikacja nie ma prawa się skończyć po zamknięciu okna DualAxis. Dwa pytania:

  1. Po czym poznajesz, że aplikacja się skończyła? Uruchamiasz z ręki, czy w jakimś IDE (Eclipse, NetBeans)?
  2. Czy nie zamykasz (ukrywasz) głównego okna podczas otwierania okna DualAxis? Jeśli tak, to musisz je sam przywrócić do życia.
0

Tak umieściłem prawdziwy kod. Mogę Ci przesłać na maila w celu sprawdzenia.

1.Piszę program w NetBeansie. Uruchamiam program poprzez F6 lub Run . Pojawia się aplikacja, naciskam guzik pojawia się nowe okno z wykresem - główne okno cały czas jest widoczne pod spodem - klikam "x" w nowym oknie z wykresem by je zamknąć i wtedy zamyka mi się nowe okno(z wykresem) jak i okno główne.
2. Nie zamykam okna głównego podczas pojawiania się nowego okna z wykresem.

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