rysowanie, dlaczego nie działa

0

Poniżej umieszczam kod który rysuje elementy schematu, natomiast nie wiem dlaczego nie działa po pierwszym kliknieciu w Jbuttona tylko znika, a po drugim kliknieciu się pojawia ?



 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
import rysowanie.*;
/*
 * Okno.java
 *
 * Created on 2011-03-12, 21:02:06
 */

/**
 *
 * @author darek
 */
public class Okno extends javax.swing.JFrame {

    /** Creates new form Okno */
    public Okno() {
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 486, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 672, Short.MAX_VALUE)
        );

        jButton1.setText("jButton1");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGap(139, 139, 139)
                .addComponent(jButton1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 269, Short.MAX_VALUE)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(35, 35, 35))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(38, 38, 38)
                        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(297, 297, 297)
                        .addComponent(jButton1)))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
        // TODO add your handling code here:
        Schemat rysuj = new Schemat(jPanel1.getWidth(), jPanel1.getHeight(), jPanel1.getGraphics());
        rysuj.NarysujStart();
        rysuj.NarysujInstrukcje("instrukcja");
        rysuj.NarysujWarunek("warunek");
    }

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Okno().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify
    private javax.swing.JButton jButton1;
    private javax.swing.JPanel jPanel1;
    // End of variables declaration

}


poniżej klasa rysująca 

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */


import java.awt.*;
/**
 *
 * @author darek
 */
public class Schemat {

   Graphics g;
   int wysokosc, szerokosc;                     
   int pozX = 0;                                
   int pozY = 0;                                
   int centerx = 40;                          
   int wspystart = 40;                        
   int wspxstart;            

   int szerokoscinstrukcji = 80;
   int wysokoscinstrukcji = 40;

   int szerokoscstartu = 80;
   int wysokoscstartu = 40;
   int pozycjanapisuX;
   int pozycjanapisuY;

   int szerokoscwarunku = 80;
   int wysokoscwarunku = 80;
   int wsppowrotuiteracjiX;
   int wsppowrotuiteracjiY;
   int wsptrueX;
   int wspfalseY;

   int stalastrzalki = 40;

  public Schemat(int wys, int szer, Graphics g){

      wysokosc = wys;
      szerokosc = szer;
      wspxstart = ((szerokosc/5)* 2);            // pozycja startu dla X
      wspystart = 40;
      this.g = g;

  }

  public void NarysujStart(){


        g.translate(wspxstart, wspystart);   
        g.setColor( Color.blue);


        g.drawOval(pozY, pozX, szerokoscstartu, wysokoscstartu);

        pozycjanapisuX = pozX + 30;
        pozycjanapisuY = pozY + 30;

        g.drawString("Start", pozycjanapisuY  ,pozycjanapisuX );

        pozY = pozY + wysokoscstartu;

        g.drawLine(centerx, pozY, centerx, pozY + stalastrzalki);

        pozY = pozY + stalastrzalki;

       int tabX [ ] = {centerx,centerx-3, centerx+3 ,centerx };
       int tabY [ ] = { pozY, pozY-5, pozY-5 , pozY };
       int n = tabX.length;
       g.fillPolygon( tabX, tabY, n-1 );

  }

    public void NarysujWarunek(String warunek){



      int tabX [ ] = {pozX, pozX + szerokoscwarunku/2, pozX + szerokoscwarunku ,pozX + szerokoscwarunku/2 , pozX };    // zamiast 0 pozX gdy bez translate
      int tabY [ ] = {pozY + wysokoscwarunku/2 , pozY,pozY + wysokoscwarunku/2 ,pozY + wysokoscwarunku, pozY + wysokoscwarunku/2 };
      int n = tabX.length;
      this.g.drawPolygon( tabX, tabY, n-1 );

      this.wsppowrotuiteracjiX = pozX + szerokoscwarunku;
      this.wsppowrotuiteracjiY = pozY + wysokoscwarunku/2;
      this.wsptrueX = pozX;
      this.wspfalseY = pozY + wysokoscwarunku/2;

      g.drawString(warunek, pozX + 5, pozY + szerokoscwarunku/2);

      pozY = pozY + wysokoscwarunku;

      //strzałka

       g.drawLine(centerx, pozY, centerx, pozY + stalastrzalki);

       pozY = pozY + stalastrzalki;

       // grot
       int tabXstrzalka [ ] = {centerx,centerx-3, centerx+3 ,centerx };
       int tabYstrzalka [ ] = { pozY, pozY-5, pozY-5 , pozY };
       n = tabXstrzalka.length;
       g.fillPolygon( tabXstrzalka, tabYstrzalka, n-1 );

  }

      public void NarysujInstrukcje(String instrukcja){

        g.drawRect(pozX, pozY, szerokoscinstrukcji, wysokoscinstrukcji );
        g.drawString(instrukcja, pozX + 5 , pozY + 20);


      pozY = pozY + wysokoscinstrukcji;

      //strzałka

       g.drawLine(centerx, pozY, centerx, pozY + stalastrzalki);

       pozY = pozY + stalastrzalki;

       // grot
       int tabX [ ] = {centerx,centerx-3, centerx+3 ,centerx };
       int tabY [ ] = { pozY, pozY-5, pozY-5 , pozY };
       int n = tabX.length;
       g.fillPolygon( tabX, tabY, n-1 );

  }

}


Aby mi się przydał musi rysować po pierwszym kliknięciu w JButona ...

0

generalnie do metod rysujących powinieneś dodać atrybut Grapgics.
Twoją klasę rozszerzyłem do JPanel
Popatrz na różnicę co jest zmienione.

public class Main extends JFrame {

    JButton but = new JButton("klik");
    JPanel pan = new Schemat();
    JPanel basic = new JPanel();

    public Main() {

        setLayout(new GridLayout(0, 1));
        add(BorderLayout.SOUTH, basic);
        basic.setLayout(new BorderLayout());
        basic.add(BorderLayout.NORTH, but);
        but.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                basic.add(BorderLayout.CENTER, new Schemat());
                basic.revalidate();
                basic.repaint();

            }
        });


    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                JFrame fr = new Main();
                fr.setVisible(true);
                fr.setSize(800, 800);
                fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            }
        });
    }
}

class Schemat extends JPanel {

    Graphics g;
    int wysokosc, szerokosc;
    int pozX = 0;
    int pozY = 0;
    int centerx = 40;
    int wspystart = 40;
    int wspxstart;
    int szerokoscinstrukcji = 80;
    int wysokoscinstrukcji = 40;
    int szerokoscstartu = 80;
    int wysokoscstartu = 40;
    int pozycjanapisuX;
    int pozycjanapisuY;
    int szerokoscwarunku = 80;
    int wysokoscwarunku = 80;
    int wsppowrotuiteracjiX;
    int wsppowrotuiteracjiY;
    int wsptrueX;
    int wspfalseY;
    int stalastrzalki = 40;

    public Schemat() {

        wysokosc = this.getHeight();
        szerokosc = this.getWidth();
        wspxstart = ((szerokosc / 5) * 2);            // pozycja startu dla X
        wspystart = 40;
        this.g = g;

    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        NarysujWarunek("warunek", g);
        NarysujStart(g);
        NarysujInstrukcje("instr", g);

    }

    public void NarysujStart(Graphics g) {
        pozX = 0;
        pozY = 0;
        g.translate(wspxstart, wspystart);
        g.setColor(Color.blue);


        g.drawOval(pozY, pozX, szerokoscstartu, wysokoscstartu);

        pozycjanapisuX = pozX + 30;
        pozycjanapisuY = pozY + 30;

        g.drawString("Start", pozycjanapisuY, pozycjanapisuX);

        pozY = pozY + wysokoscstartu;

        g.drawLine(centerx, pozY, centerx, pozY + stalastrzalki);

        pozY = pozY + stalastrzalki;

        int tabX[] = {centerx, centerx - 3, centerx + 3, centerx};
        int tabY[] = {pozY, pozY - 5, pozY - 5, pozY};
        int n = tabX.length;
        g.fillPolygon(tabX, tabY, n - 1);

    }

    public void NarysujWarunek(String warunek, Graphics g) {


        pozX = 0;
        pozY = 0;
        int tabX[] = {pozX, pozX + szerokoscwarunku / 2, pozX + szerokoscwarunku, pozX + szerokoscwarunku / 2, pozX};    // zamiast 0 pozX gdy bez translate
        int tabY[] = {pozY + wysokoscwarunku / 2, pozY, pozY + wysokoscwarunku / 2, pozY + wysokoscwarunku, pozY + wysokoscwarunku / 2};
        int n = tabX.length;
        g.drawPolygon(tabX, tabY, n - 1);

        wsppowrotuiteracjiX = pozX + szerokoscwarunku;
        wsppowrotuiteracjiY = pozY + wysokoscwarunku / 2;
        wsptrueX = pozX;
        wspfalseY = pozY + wysokoscwarunku / 2;

        g.drawString(warunek, pozX + 5, pozY + szerokoscwarunku / 2);

        pozY = pozY + wysokoscwarunku;

        //strzałka

        g.drawLine(centerx, pozY, centerx, pozY + stalastrzalki);

        pozY = pozY + stalastrzalki;

        // grot
        int tabXstrzalka[] = {centerx, centerx - 3, centerx + 3, centerx};
        int tabYstrzalka[] = {pozY, pozY - 5, pozY - 5, pozY};
        n = tabXstrzalka.length;
        g.fillPolygon(tabXstrzalka, tabYstrzalka, n - 1);

    }

    public void NarysujInstrukcje(String instrukcja, Graphics g) {

        g.drawRect(pozX, pozY, szerokoscinstrukcji, wysokoscinstrukcji);
        g.drawString(instrukcja, pozX + 5, pozY + 20);


        pozY = pozY + wysokoscinstrukcji;

        //strzałka

        g.drawLine(centerx, pozY, centerx, pozY + stalastrzalki);

        pozY = pozY + stalastrzalki;

        // grot
        int tabX[] = {centerx, centerx - 3, centerx + 3, centerx};
        int tabY[] = {pozY, pozY - 5, pozY - 5, pozY};
        int n = tabX.length;
        g.fillPolygon(tabX, tabY, n - 1);

    }
}

 
0

Hmm ja potrzebuje klasę z metodami NarysujWarunek, NarysujStart itd, oraz polami które będą przechowywały informacje takie jak aktualna pozycja x, y oraz wiele innych gdyż zadaniem tej klasy jest wygenerowanie schematu podczas analizy algorytmu zapisanego w jezyku java, wiec ja nie wywołuje za każdym razem sekwenjcji metod :

    NarysujWarunek("warunek", g);
    NarysujStart(g);
    NarysujInstrukcje("instr", g);

Jesli w kodzie analizowanym będe miał 10 instrukcji jedna po drugiej, to analizator wywoła 10 razy metode NarysujInstrukcje :)

Najlepiej odpowiadało by mi rozwiązanie które napisałem, tylko musiało by wyrysować schemat po pierwszym kliknięciu i nie znikać, problem w tym że nie wiem czy jest to możliwe do zrealizowania ...

Nie wiem czy masz na myśli to co opisze poniżej podsyłając mi powyższy kod ....

Jedną z opcji jest zbudowanie dla każdego elementu (tzn np: NarysujInstrukcje ) zbudować klasę, klasy te musiały by być rozszerzeniem klasy która dziedziczy po klasie Jpanel i jednocześnie posiada pola takie jak pozX, PozY, każdy obiekt reprezentujący dany element ma możliwość modyfikowania wartości pola nadklasy pozX itd (myśle że dobrze to ująłem :)),

public class Schemat extends JPanel // klasa po której będą dziedziczyć klasy rysujące poszczególne elementy takie jak NarysujWarunek("warunek", g);

public class Warunek extends Schemat // klasy dla poszczególnych elementów w tym przypadku odpowiednik metody NarysujWarunek

Jednak nie wiem czy da się to zrobić ? w jaki sposób deklarować pola w klasie bazowej Schemat, aby mogły się odwoływać do niej obiekty klas reprezentujących elementy Schematu jak i modyfikować je ?

0

Wie ktoś jak można to rozwiązać ?

0

Masz chyba złe podejście do rysowania. Jeżeli rysujesz na panelu, to cały rysunek powinna wykonać metoda paintComponent() panelu. "Główna" klasa programu tworzy kolekcję obiektów do narysowania, po każdej zmianie tej kolekcji wywołuje metodę repaint() panelu z rysunkiem. Komponenty do narysowania mogą być różnych typów, metoda paintComponent() rozpoznaje typ komponentu i wywołuje odpowiednią metodę, np. narysujSchemat();

0

Mam do ciebie prośbę czy mógł byś mi na przykładzie przybliżyć to co napisałeś, bo nie rozumie tego tak do końca (najlepiej w oparciu o mój program ) ?

0

Twój kod, uwagi i pytania świadczą, że chcesz napisać program, który znacznie przekracza Twoje aktualne umiejętności i rozumienie Javy.

0

nie zaprzeczam bo to mój pierwszy program w javie i pierwszy obiektowy, natomiast muszę go napisać a czasu nie pozostało mi zbyt dużo ;/

Każdy komponent ma metodę paintComponent(), napisałeś aby metoda paintComponent() Panelu narysowała cały rysunek,
Głowna klasa programu tworzy kolekcję obiektów do narysowania - masz na myśli utworzenie klas dziedziczących po wybranym komponencie (elementów schematu)?
tylko jak w tym momencie za pomącą metody paintComponent głównego panelu na którym będe rysował, narysować cały rysunek ? (metodę paintComponent mogę wywołać chyba tylko raz ? )

0

Klasa główna (Okno) tworzy kolekcję elementów schematu. Zakładam, że na starcie programu nie jest jeszcze znany schemat - nie wiadomo z jakich elementów będzie się składał. Klasa Schemat powinna dziedziczyć po klasie JPanel. W konstruktorze powinieneś przekazać do klasy Schemat referencję do klasy Okno.

//w klasie Okno
JPanel panel=new Schemat(this,...)
//w klasie Schemat
public Schemat(Okno mainWindow,..)
//w konstruktorze klasy Schemat możesz ustawić pożądany rozmiar tego Panelu
setPreferredSize(new Dimension(...)); 

Metoda paintComponent(Graphics g) klasy Schemat powinna wyglądać tak:

  super.paintComponent(g); //wyczyści obszar panelu
  //odczytanie kolekcji elementów schematu, coś w rodzaju
  elementy=mainWindow.getElementy();
  //pętla rysująca
  for(int i=0;i<elementy.size();i++)
  {
      ...=elementy.get(i);
      //rozpoznanie jakiego typu jest element schematu, najprościej gdyby różne elementy były z różnych klas (Warunek, Start, Koniec, Instrukcja).
      //narysowanie elementu schematu
  }

W klasie Okno po dodaniu elementu do kolekcji elementów schematu wywołujesz panel.repaint(), nie panel.paintComponent().

0

Ok dzięki:)

Podczas wczytywania kolejnych elementów kolekcjii piszesz że najprościej gdyby różne elementy były z różnych klas (Warunek, Start, Koniec, Instrukcja).

Mam rozumieć w tym momencie że obiekt Warunek, Linia czy instrukcja zawierał by tylko wartości opisujące element (szerokość, wysokość położenie itp )?
Następnie po wczytaniu obiektu opisującego element następuje narysowanie go zgodnie z danymi zawartymi w obiekcie ?

0

Mniej więcej.

public abstract class Element
...
public class Warunek extends Element
{
     public void narysujSie(Graphics g)
     ....
...
//definicja kolekcji
ArrayList<Element> elementy=new ArrayList<Element>();
//w metodzie paintComponent()
  elementy.get(i).narysujSie(g);
0

Mam problem z przekazaniem kolekcji do konstruktora klasy schemat, po wywołaniu instancji klasy Schemat nie ma kolekcji w niej, poniżej zamieszcze kod


// deklaracja klasy Schemat 

public class Schemat extends JPanel{

    ArrayList <Element> elementy;

    public void Schemat(ArrayList zbior){

        elementy = zbior;

    }

  public void paintComponent(Graphics g){
  super.paintComponent(g); //wyczyści obszar panelu

  for(int i=0;i<elementy.size();i++)
  {

       elementy.get(i).narysujSie(g);
  }

        
    }

// poniżej wywołanie rysowania poprzez utworzenie obiektu klasy Schemat w oknie głównym

        ArrayList<Element> elementy=new ArrayList<Element>();
        elementy.add(i,(Element) new BlokStart());
        i++;
        elementy.add(i,(Element) new Linia());

//zbiorschematow to obiekt JTabbedPane, pponieważ schematów będzie więcej gdyż będe generował je do każdej deklaracji funkcji w kodzie
        zbiorschematow.add("schemat1", new Schemat(elementy));

Mam jeszcze jedno pytanie, gdyż wszystkie obiekty to dziedziczą po klasie abstrakcyjnej, natomiast ja potzrebuje aby zmienne takie jak pozycjaX były dostępne dla wszystkich tworzonych obiektów oraz modyfikowane przez nie same i dostępne dla kolejnych ... w jaki sposób zadeklarować te zmienne i jak się odwoływać do nich, aby można było je modyfikować ?

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