Przycisk do włączania nowego okna w programie.

0

Witam wszystkich.

Jestem bardzo początkujący z języka Java i dlatego mam problem [green]

Staram się stworzyć program, który będzie mi pobierał dane z pliku, następnie przeliczał je według pewnego algorytmu i wyniki umieszczał w tabeli. Jak do tej pory wszystko mi wychodziło. Mam więc już okno program z dwoma przyciskami. Pierwszy przycisk służy do otwierania pliku (działa), a drugi przycisk będzie służył do prezentacji graficznej danych (wykres). I tutaj zaczynają się schody. Jaki kod napisać w programie, aby podczas kliknięcia w ten właśnie przycisk otwierało się nowe okno, w którym będzie już wykres?
Jak na razie mam to:

public void actionPerformed(ActionEvent e) {

    if (e.getSource() == openButton) {
        int returnVal = fc.showOpenDialog(Hurst.this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
          
                File file = fc.getSelectedFile(); 
                
                log.append("Otwieranie: " + file.getName() + "." + newline);
	log.append("Liczba linii w pliku wynosi " +i +"." + newline);
        } else {
            log.append("Operacja przerwana przez użytkownika." + newline);
        }
        log.setCaretPosition(log.getDocument().getLength());
     }

Zdaje mi się, że powinienem użyć else if, jednak nie wiem do końca jak, a tym bardziej jak na nim wymusić uruchomienie nowego okna.
Proszę o pomoc.
0

Użyj komponentu JInternalFrame np.:
JInternalFrame ramka = new JInternalFrame("Moja nowa ramka", true, true);

Pozdro

0

Dzięki za odpowiedź. Już wcześniej wyczaiłem te wewnętrzne ramki, jednak nie za bardzo wiem jak sprawić, aby działały. Jak mam to drugie okno uruchomić ?? Bo chyba coś takiego nie wystarczy:)

	else if (e.getSource() == wykres) {
                       JInternalFrame ramka = new JInternalFrame("Moja nowa ramka", true, true);
                        
                        ramka.pack();
	               ramka.setVisible(true);
                            }

HELP:)

0

Aby JInternalFrame była widoczna musisz ją dodać do kontenera dla wewnętrznych okienek, tzn JDesktopPane

0

Niestety, chyba jestem za głupi, bo nie potrafie tego uruchomic. Po prostu nie rozumiem. Siedze na cholernym tutorialu Suna i nic :/
Mam to:

import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.filechooser.*;
import javax.swing.event.*;

public class Hurst extends JPanel
                             implements ActionListener {
    static private final String newline = "\n";
    JButton otworz,  wykres;
    JTextArea log;
    JFileChooser fc;
    JDesktopPane desktop;

 public Hurst() {
        super(new BorderLayout());

        log = new JTextArea(5,20);
        log.setMargin(new Insets(5,5,5,5));
        log.setEditable(false);
        JScrollPane logScrollPane = new JScrollPane(log);

        
        fc = new JFileChooser();
            
        otworz = new JButton("Otwórz plik...");
        otworz.addActionListener(this);

        wykres = new JButton("Pokaż wykres...");
	
        wykres.addActionListener(this);
       
        JPanel buttonPanel = new JPanel(); 
        buttonPanel.add(otworz);
        
	buttonPanel.add(wykres);
        
        add(buttonPanel, BorderLayout.PAGE_START);
        add(logScrollPane, BorderLayout.CENTER);
    }

    public void actionPerformed(ActionEvent e) {

        
        if (e.getSource() == openButton) {
            int returnVal = fc.showOpenDialog(Hurst.this);

            if (returnVal == JFileChooser.APPROVE_OPTION) {
                File file = fc.getSelectedFile();

                log.append("Otwieranie: " + file.getName() + "." + newline);
		log.append("Liczba linii w pliku wynosi " +i +"." + newline);
            } else {
                log.append("Operacja przerwana przez użytkownika." + newline);
            }
            log.setCaretPosition(log.getDocument().getLength());
	}
	else if (e.getSource() == wykres) {
           
	<font color="red"><<i tutaj potrzebuje aby wyświetlał mi nowe okno>></font>
               
            } else {
                log.append("Operacja przerwana przez użytkownika." + newline);
            }
            log.setCaretPosition(log.getDocument().getLength());
     
    
    }    

</i>
0

To, że zadeklarujesz obiekt JDesktopPane desktop nic Ci nie da, bo musisz jeszcze go podłączyć do interfejsu. Proponuję obiekt log dodać w miejsce SOUTH, a obiekt desktop do CENTER. Oczywiście wcześniej musisz wywołać konstruktor JDesktoPane. W metodzie obsługi zdarzenia wykonujesz:

  • utworzenie JInternelFrame
  • ustalenie rozmiaru
  • dodanie okienka do desktop: desktop.add(nazwa_okienka)
  • włączenie wyświetlania: setVisible(true)
0

Luuki byłbym wdzięczny, gdybyś to zaprezentował na kawałku kodu. Staram sie to pojąć ale nie potrafie, a czas mnie nagli :-(
Skrótowo co zrozumiałem i zrobiłem w programie:


public class Hurst extends JPanel
                             implements ActionListener {
    
JDesktopPane desktop;
...
 public Hurst() {
        super(new BorderLayout());
             ...
             desktop = new JDesktopPane();
             ...
             add(desktop, BorderLayout.CENTER);
            }

}

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == openButton) {
            int returnVal = fc.showOpenDialog(Hurst.this);

            if (returnVal == JFileChooser.APPROVE_OPTION) {
                File file = fc.getSelectedFile();

  log.append("Otwieranie: " + file.getName() + "." + newline);
		log.append("Liczba linii w pliku wynosi " +i +"." + newline);
            } else {
                log.append("Operacja przerwana przez użytkownika." + newline);
            }
            log.setCaretPosition(log.getDocument().getLength());
	}
	else if (e.getSource() == wykres) {

	JInternalFrame ramka = new JInternalFrame("Moja nowa ramka", true, true);
	
	desktop.add(ramka);
	ramka.setVisible(true);
         
	    
              
    }
...

Program się uruchamia, ale wciskanie przycisku nic nie daje :-(
Prosze, popraw ten kod tak jak powinien być. Z góry dziękuje.

0

Już działa !!! [green]

WIELKIE DZIĘKI CHŁOPAKI :-)

Teraz kolejne pytanie mam. Jak zrobic do tego prosty wykresik, który będzię pobierał X i Y z dwóch tabel znajdujących się w tym programie? Jak to wkomponować do metody obsługi zdarzenia z przycisku wykres??

0

Juz narysowalem prosta linie. Jednak na wykresie potrzebuje punktow. Punkty te beda sie skladaly tak jak napisalem wyzej z x i y umieszczonych w dwoch roznych tabelach. Jest tylko jeden problem , dane te sa typu double , a tutaj wchodzi int. Da sie jakos inaczej :| ?

0

Konwerjse mozesz zrobic poprzez metode round z klasy Math lub poprzez rzutowanie. Ja osobiscie robie to tak:

double a =2.0;
int b = (int) Math.round( b );

0

Ehh... musi sie dac jakos inaczej, na liczbach rzeczywistych :( Bo jak ja mam wartosci kolejne rzedu:

9,056
9,745
9,003

itp, to jak obetne wszystko po przecinku to lipa, nawet przy zaokrąglaniu... jak z tego wybrnąć??

0

To powiedz dokladnie do czego ci to zaokraglenie potrzebne? Jak wartosc y na wykresie? to musisz sobie wykres jakos przeskalowac ze nie traktowac jednego piksela jako 1 na wykresie.

0
Coven napisał(a)

J. Jest tylko jeden problem , dane te sa typu double , a tutaj wchodzi int.

Tego nie rozumiem. Gdzie wchodzi int?

0

To są wartości ln z różnych liczb w dwóch tablicach. Jedna to powiedzmy jest: lnS[n] , druga LnVar[s].
Tylko lnVar[n] zawiera liczby w formacie double - to jest Y , lnS[n] zmienia się co 1 (wiec to moge zamienic na int) i to jest mój X.
próbowałem zrobić coś w stylu:

for(j=0;j<=10;j++) {

    x = lnS[j];
    y = lnVar[j];
g2d.draw(x,y,x,y);

Ale nie dość że nie chce bo typy sie nie zgadzają, to jeszcze zaczyna o d góry :-) A wartości muszą być double.
Nawet nie wiem jak narysować oś X i Y, oraz jak ją oznaczyć. A do tych punktów muszę później aproksymacje zrobić, normalnie porażka, a zostało mi 2 tygodnie max czasu :-( Najgorsze jest to, że nie znalazłem żadnego dobrego tutoriala do wykresów w Javie, ten Suna to szkoda gadać...

0

Okej to cos ode mnie:

  1. RTFM! czyli czytaj w java api reference o rysowaniu. Mozna rysowac bezposrednio z doubli. robi sie to tak:
    g2d.draw( new Line2D.Double( x1, y1, x2, y2 ). To wszystko jest api. bez zagladania do api nic nie zrobisz.

  2. A teraz cos na temat twojego wykresu:

Os OX:

g2d.draw( new Line2D.Double( 20, this.getHeight()/2, this.getWidth() - 20, this.getHeight / 2 ));

Narysuje ci pozioma linie w polowie wysokosci komponentu zaczynajaca sie od 20 piksela od lewego brzegu i konczaca 20 pikseli przed prawym brzegiem.

strzalka:

g2d.draw( new Line2D.Double( 20, this.getheight()/2, 30, this.getHeight()/2 + 10 ));
g2d.draw( new Line2D.Double( 20, this.getheight()/2, 30, this.getHeight()/2 - 10 ));

Narysuje grot strzalki.

Opiszmy ja:

g2d.drawString( "X", this.getWidth() - 20 , this.getHeight() - 20 );

To samo dla osi OY:

g2d.draw( new Line2D.Double( this.getWidth/2, 20, this.getWidth/2, this.getHeight - 20 ));
g2d.draw( new Line2D.Double( this.getWidth/2, 20, this.getWidth/2 - 10, 30));
g2d.draw( new Line2D.Double( this.getWidth/2, 20, this.getWidth/2 + 10, 30 ))
g2d.drawString( "Y", this.getWidth()/2 + 20, 20 );

Dobra a teraz pokaze ci jak rzutowac punkt, jezeli nie bedzie umial dodac do tego skalowania to pomoge ci ale musisz samemu cos zrobic:

public void drawPoint( Graphics2D g2d, double realX, double realy )
{
    // nasz srodek wykresu jest w punkcie (getWidth/2, getHeight/2) czyli musimy wszystkie punkty       
    //przesuwac wedlug tego punktu

    double newX = realX + getWidth()/2;
    double newY = realY*-1 + getHeight()/2;

    g2d.draw( new Line2d.Double( newX, newY, newX, newY ));

}

Powinno dzialac. W razie czego pisz tutaj.
ps w Javie robi sie wykresy tak samo jak w innych jezykach programowania.
ps2. zaloz sobie konto latwiej nam sie bedzie komunikowac.
ps3. przeskaluj sie jakos te wykresy

0

Masz dwa rozwiązania:

  • przeskalować wyniki do wybranej dokładności, tzn. jeśli chcesz wyświetlać z dokładnością do 0.01 wykonujesz operację wartość_real * 100. Czyli w efekcie 1 pixel to 0.01. Po przemnożeniu możesz użyć metody round lub rzutowania aby obciąć to co po przecinku.
  • użyć biblioteki do wykresów, np. JFreeReport http://www.jfree.org/jfreereport/index.php
0

Garar dzięki... czytam api jakby co, tylko nie zawsze z pełnym zrozumieniem :-D Luuki też dzięki, właśnie siedze nad tym skalowaniem.

class MyComponent extends JComponent {
             public void paint(Graphics g) {
                 Graphics2D g2d = (Graphics2D)g;
			 double x, y;
               
g2d.draw( new Line2D.Double( 20, this.getHeight()-20, this.getWidth() - 20, this.getHeight()-20 )); //oś X

g2d.draw( new Line2D.Double( 970, this.getHeight()-10, 980, this.getHeight()-10 - 10 ));  // strzalka
g2d.draw( new Line2D.Double( 970, this.getHeight()-30, 980, this.getHeight()-30 + 10 )); //  strzalka
g2d.draw( new Line2D.Double( this.getWidth()-970, 20, this.getWidth()-970, this.getHeight() - 20 )); // os Y

g2d.drawString( "lnS", this.getWidth() - 40 , this.getHeight() - 40 ); //nazwa
g2d.draw( new Line2D.Double( this.getWidth()-970, 10, this.getWidth()-970 - 10, 20));
g2d.draw( new Line2D.Double( this.getWidth()-970, 10, this.getWidth()-970 + 10, 20 ));


g2d.draw( new Line2D.Double( this.getWidth()-950, 442, this.getWidth()-950, this.getHeight() - 15 )); //linia w poziomie
g2d.draw( new Line2D.Double( this.getWidth()-930, 442, this.getWidth()-930, this.getHeight() - 15 )); //linia w poziomie
//g2d.draw( new Line2D.Double( this.getWidth()-965, 20, this.getWidth()-960 - 15, 20)); //-linia w pionie
g2d.draw( new Line2D.Double( this.getWidth()-965, 427, this.getWidth()-960 - 15, 427)); //-linia w pionie
g2d.draw( new Line2D.Double( this.getWidth()-965, 407, this.getWidth()-960 - 15, 407)); //-linia w pionie
g2d.draw( new Line2D.Double( this.getWidth()-965, 387, this.getWidth()-960 - 15, 387)); //-linia w pionie
g2d.draw( new Line2D.Double( this.getWidth()-965, 367, this.getWidth()-960 - 15, 367)); //-linia w pionie
g2d.draw( new Line2D.Double( this.getWidth()-965, 347, this.getWidth()-960 - 15, 347)); //-linia w pionie
g2d.draw( new Line2D.Double( this.getWidth()-965, 327, this.getWidth()-960 - 15, 327)); //-linia w pionie
g2d.draw( new Line2D.Double( this.getWidth()-965, 307, this.getWidth()-960 - 15, 307)); //-linia w pionie

g2d.drawString( "lnVar", this.getWidth()-960 + 20, 20 );
	 
                for(j=0;j<9;j++){ 
		   x=40 ;// =1 na osi x
                   y=427; // =1 na osi Y
               
              g2d.draw( new Line2D.Double( x, y, x, y ));
 
	} 

Wykorzystałem ten kod, który tutaj mi podałeś Garar, jednak musiałem się troszke pobawić, bo potrzebna mi była tylko jedna ćwiartka. Ale dałem rade. Mam ramke rozmiaru 1000 (szerokość) i 500 wysokość. Teraz mam pytanie, jak najlepiej zeskalować te wyniki , które mam. Tutaj chce wykorzystać g2d.draw( new Line2D.Double( x, y, x, y ))
Napisze jakie ogólnie wartości mam dla X i Y:

X Y
15,3832 10,5713
15,3572 10,5966
15,3319 10,6213
15,3017 10,6454
... ...

Dopiero 2 miejsce po przecinku daje różnice między liczbami. Jak zrobić to na moim układzie wsp?
Będe siedział sam nad tym, jednak gdybyście mogli coś podpowiedzieć jak to najlepiej rozwiązać byłbym bardzo wdzięczny. Dzięki wielkie za wszystko!!!

0

No to tak:

X Y
15,3832 10,5713
15,3572 10,5966
15,3319 10,6213
15,3017 10,6454
... ...

Ja bym to zrobil X w przedziale od 15 do 16 a Y w przedziale od 10 do 11 albo jeszcze zmniejszyl przedzial
A wracajac do rzeczy:

double realX = ((X-15)/1) * this.getWidth();

i tam tak 15 i 1 mozesz zastapic swoimi liczbami to bedzie po prostu poczatek zakresu X i jego wielkosc. W tym wypadku X sa z przedzialu od 15 do 16 i dlatego przedzialu sie DOBRZE narysuja.
Dowod:
(15 - 15)/1 * this.getWidth() = 0; // dolna granica
(16 - 15)/1 * this.getWidth() = this.getWidth(); // gorna granica

(16.1 - 15 )1* this.getWidth() = this.getWidth*1.1; // powyzej gornej granicy nie narysuje sie

Wtedy wylkres nie bedzie sie zaczynal od 0 ale od 15, musisz tylko na osi X podpisac to.
get.Width() to ta twoja wysokosc, to pozwoli na przeskalowanie.

To samo dla Y.

double realY =((Y - 10)/1) * this.getWidth();

Moze to tez jeszcze bardziej sciesni i zrobic zakres od 10.2 o dlugosci 0.4 na przyklad ale wartosci musza byc w tym przedziale.

A potem lyp:

 g2d.drawLine2d( realx, realy, realx, realy ); // albo cos takiego wiesz juz jak sie punkty rysuje

To powinno pomoc mam nadzieje ze za bardzo nie zamieszalem.

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