Container i panele

0

Witam.
Chciałbym zrobić okno, które składa się z dwóch pomniejszych okien. Jednego po lewej, w którym byłoby menu, a drugiego po prawej, który byłby "obszarem rysowania". Chcialem w ten sposób wykluczyć możliwość, ze jak ktoś da np. współrzędne obrazkowi 0,0, to żeby nie wchodził on na menu, tylko domyślne 0,0 było już poza tym menu.

Mam taki konstruktor okna:
public SmpWindow()
{
Container contents = getContentPane();
contents.add(new Menu());
contents.add(new DrawWndPane());
}

Menu to okno z menu, a DrawWndPane to okno rysowania. Niestety jak oba okna są dodane, to wyświetla tylko to drugie :/ Jak to naprawić?

0

Ustawić layout na okno.

0

Poczytaj o menadżerach rozkładu.
Masz dwa wyjścia.
Zmienić menadżera dla JFrame (domyślnie jest BorderLayout, którego metoda add(..) wymaga dwóch argumentów: komponent, gdzie_umieścić. Jeśli nie podasz drugiego argumentu, to komponent jest umieszczany w centrum okna, w konsekwencji widać tylko ostatnio dodany komponent.
Podawać drugi argument:

            contents.add(new Menu(),BorderLayout.WEST);
            contents.add(new DrawWndPane(),BorderLayout.CENTER);   
0

Dzięki, po dodaniu drugiego argumentu działa.
Tylko teraz muszę z obu okien usunąć setLayout(null), bo inaczej nie działa. A w takim wypadku ustawione klawisze lecą ciurkiem, a nie jedno po drugim :/ Ja chciałbym im podać położenie.

0

Jak wyłączysz menadżera, to rozmiar i lokalizację komponentu wyznaczasz metodą setBounds(...).

0

To to wiem, ale...
Jeśli w Menu() mam setLayout(null) to wtedy wyświetla mi tylko drugie okienko.
Gdy skasuje to setlayout, albo dam tam BorderLayout, to oba okienka są, tylko, ze wtedy przyciski leżą w rządku na górze, mimo użycia metody setBounds().

0

Daj w oknie Menu GridLayout z jedną kolumną (i tyle wierszy ile jest przycisków).

0

Dzięki :D Co prawda wolałbym sam ustawić, w którym miejscu będą przyciski, i wolałbym żeby nie były tak grube, ale lepszy rydz niz nic ;)

Zapewne będe mieć jeszcze dziś parę pytań, więc miło byłoby, gdybyś "bo" zajrzał jeszcze do tego tematu później (o ile bedziesz miec czas i ochote pomagac :P).

0

Mnie się też nie podobają efekty działania GridLayout, swego czasu napisałem własnego menadżera VerticalLayout to rozmieszczania elementów w jednej kolumnie.

0
  1. Można kolorować przyciski? Jeśli tak, to jak? Jeśli tzreba się z tym duzo bawić, to moge sobie odpuścić, ale jeśli to tylko jakas prosta komenda, to zawsze ejst to jakies urozmaicenie ;)

  2. W oknie po lewej (Menu) mam przyciski. Po kliknięciu na któryś z nim, chcę by w oknie po prawej (DrawWndPane) wyświetlił sie obrazek odpowiadający przyciskowi.
    Mam zrobione wychwytywanie zdarzeń, z napisanem metody rysującej też, ale chyba musze przekażać jakiś kontekst graficzny czy coś?
    Bo w DrawWndPane mam taką metodę:

public void paintComponent(Graphics g)
   {
	   super.paintComponent(g);
       Graphics2D  g2d = (Graphics2D)g;
       g2d.drawLine(0, 0, getSize().width, getSize().height);
   }

I ona powoduje, ze w tym oknie ejst to Od razu narysowane. A ja chciałbym żeby tak się dopiero rysowało po kliknięciu przycisku 1. I chciałbym mieć inne metody, który byłyby dopasowane do konkretnych przycisków.

0

I jeszcze jedno - jeśli ktoś chciałby pomóc mi "w czasie rzeczywistym" ;) to mój numer gg to 8158446

0

Wcześniejsze pytanie nieaktualne. Jakoś sobie poradziłem.

Jak można czyścić panel rysowania, ale przy okazji nie usuwać tła?
Bo mam takie coś:
g2d.clearRect(0,0,getSize().width, getSize().height);
I to czasem nie usuwa tła, a czasem robi je białe :/

0

Mam problem i to spory.
Mam coś takiego w rysowaniu:

  public void paintComponent(Graphics g)
   {
       super.paintComponent(g);
       Graphics2D  g2d = (Graphics2D)g;
       g2d.setFont(new Font(null, Font.BOLD, 18));
       g2d.setColor(new Color(200, 200, 200));
       g2d.drawString("Witam w moim programie", getSize().width/2-100, getSize().height/2);
       Line2D.Double  line = new Line2D.Double( 0, 0 , getSize().width, getSize().height );
       g2d.draw( line );
   }
   
   public void paint1(Graphics g) {
       Graphics2D  g2d = (Graphics2D) g;
       g2d.clearRect(0,0,getSize().width, getSize().height);
       Line2D.Double  line = new Line2D.Double( 0, 0 , getSize().width, getSize().height );
       g2d.draw( line );
   }

Metoda paintComponent rysuje od samego właczenia programu. Obrazek ten nie znika przy chowaniu okna za ekran.
Metoda paint1 jest wywoływana gdy wcisne przycisk 1. No i ten obrazek neistety znika, gdy wyjde za ekran :/ Jak mam to naprawić?

0

Całym rysowaniem powinna się zajmować metoda paintComponent(). Naciśnięcie przycisku winno zmieniać wartość jakiegoś pola, a kod rysujący (zawarty w paintComponent()) powinien rysować (bądź nie) w zależności od wartości tego pola.

0

Np. tak

class PanelFigur extends JPanel
{
    private Figury parent;
    //------------------------
    public PanelFigur(Figury parent)
    {
        super();
        this.parent=parent;
        setPreferredSize(new Dimension(400,300));
    }
    //------------------------
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        if(parent.stan.equals("P") || parent.stan.equals("B"))
        {
            drawRectangle(g);
        }
        if(parent.stan.equals("E") || parent.stan.equals("B"))
        {
            drawEllipsis(g);
        }
    }
    //------------------------
    private void drawRectangle(Graphics g)
    {
        g.setColor(Color.GREEN);
        g.fillRect(0,0,100,100);
    }
    //------------------------
    private void drawEllipsis(Graphics g)
    {
        g.setColor(Color.BLUE);
        g.fillArc(50,50,200,100,0,360);
    }
}

parent, to referencja do klasy(okna), w którym są przyciski

0

Dzięki za odpowiedź, ale dalej mi nie działa. Pewnie gdzies robię głupi błąd, ale nie widzę gdzie :P
Mam tak:

class Menu extends JPanel implements ActionListener
{
    public int opcja;
    
    Menu() {
        super();
        
       ...
        
        b1.addActionListener( this );
        ...
        
        opcja = 0;
        
    }

     public void actionPerformed(ActionEvent event)
       {
         Object source = event.getSource();
         if ( source == b1 )
             opcja = 1;
       }
}

class DrawWndPane  extends JPanel
{
    private Menu parent;
    
   DrawWndPane(Menu parent)
   {
       super();
       this.parent = parent;
       setLayout( null );
   }
   
   public void paintComponent(Graphics g)
   {
       super.paintComponent(g);
       
       if(parent.opcja==0) {
           Graphics2D  g2d = (Graphics2D)g;
           g2d.setFont(new Font(null, Font.BOLD, 18));
           g2d.setColor(new Color(200, 200, 200));
           g2d.drawString("Witam w moim programie", getSize().width/2-100, getSize().height/2);
           Line2D.Double  line = new Line2D.Double( 0, 0 , getSize().width, getSize().height );
           g2d.draw( line );
       }
       if (parent.opcja==1)
           paint1(g);
       
   }
   
   public void paint1(Graphics g) {
       Graphics2D  g2d = (Graphics2D) g;
       g2d.clearRect(0,0,getSize().width, getSize().height);
       Line2D.Double  line = new Line2D.Double( 0, 0 , getSize().width, getSize().height );
       g2d.draw( line );
   }
}

class SmpWindow extends JFrame  
{    
    public SmpWindow()
    {       
        ...
        }
    }

}

No i mi teraz przycisk 1 nie działa w ogóle. Wyswietla się tylko to, gdy ejst opcja=0.

0

A słyszałeś o debugowaniu?

     public void actionPerformed(ActionEvent event)
       {
         Object source = event.getSource();
         if ( source == b1 )
             opcja = 1;
         System.out.println("dupa "+opcja);
       }
.....
   public void paintComponent(Graphics g)
   {
       super.paintComponent(g);
       System.out.println("dwie dupy "+parent.opcja);

       
0

Słyszałem :P
Dodałem metodę repaint() na koniec paintComponent i działa teraz. Tylko teraz tło mi się robi całe białe. Jak to naprawić?
Wiem, że to jest z powodu metody:
g2d.clearRect(0,0,getSize().width, getSize().height);
Używam jej, by rysować zawsze na czystym obszarze rysowania. Tylko, ze jak ją sie wywoła pod rząd to tlo się robi białe...

I przepraszam bo, jeśli Cię denerwują moje pytania, ale to są dopiero moje początki z grafiką w Javie :P

0

Ok, dałem validate() zamiast tamtego i tło zostaje takie jakie było.
Dzieki za pomoc. Później wrócę z innymi pytaniami, jak mi znów coś nie będzie wychodzić :P

0

Mea culpa, nie w tym miejscu repaint(). Repaint() w klasie z przyciskami po każdej zmianie wartości zmiennej opcja.
P.S. Na razie mnie nie denerwujesz, z postów wynika, ze myślisz nad kodem.

0
bo napisał(a)

Mea culpa, nie w tym miejscu repaint(). Repaint() w klasie z przyciskami po każdej zmianie wartości zmiennej opcja.

Jak przeniosłem repaint(). czyli mam:

public void actionPerformed(ActionEvent event)
	   {
		 Object source = event.getSource();
		 if ( source == b1 ) {
			 opcja = 1;
			 repaint();
		 }
		 else if ( source == b2 ) {
			 opcja = 2;
			 repaint();
		 }
	   }

a w PaintComponent usunąłem repainta(), to nie działa już. Tzn. zmienia opcję, przechodzi przez repaint, ale nie pojawia się obrazek.

0

A jak są powiązane klasy? Repaint() w oknie z przyciskami wywołuje repaint() na każdym panelu (canvasie) umieszczonym w tym oknie. Jeżeli okno z rysunkiem nie leży w oknie z przyciskami (tzn. nie zostało dodane metoda add()), to musisz wywołać repaint() na rzecz okna z rysunkiem:

referencja_do_okna_z_rysunkiem.repaint();
0

To sa osobne panele. Ale już sobiez tym poradziłem i repainty są po każdej zmianie opcji ;)
Na razie wszystko działa, walczę z innymi możliwościami graficznymi w Javie :P
Dzięki wielkie za pomoc. I pewnie sie jeszcze później/jutro odezwę tu na forum z prośbą o pomoc ;)

0

Chciałbym w Menu dodać opcję Zamknij. Zawsze robiłem to metodą dispose(), ale to działało gdy było tylko jedno okno. Teraz Menu jest rozszerzeniem JPanel a nie JFrame i dispose() nie działa. Da się to zrobić jakos inaczej?

0

Bawię się teraz klasą ImageIO. Ma ona metodę write, która zapisuje do pliku.
Jak zapisac do pliku ten obraz, który jest teraz wyświetlony? Bo mam parę metod rysujących i chciałbym zrobić jedną uniwersalną metodę zapisującą.

0
  1. System.exit(0);
  2. Poszukaj na forum, było.
0

Dzięki za ten exit.
Jesli chodzi o moje drugie pytanie, to chodzi mi tylko o to jaką klasą/metodą mogę "wczytać" obraz z mojego panelu do jakiejś zmiennej, bo z samym zapisem to sobie poradzę. A na razie znalazłem tylko o złapaniu całego ekranu (monitora) :/

0

I jeszcze jedno.
Czy obrazek BufferedImage mozna jakos łatwo przeskalować? BO wczytuję taki obrazek do okna i chciałbym, żeby się od razu dopasował do wielkości okna.

0
bo napisał(a)

Poszukać to nie łaska?
http://4programmers.net/Forum/608334?h=BufferedImage#id608334

Szukałem, ale w googlach. I jak widac, niezbyt udolnie :P
Wykorzystałem to w swojej metodzie:
public void zapisz(Graphics g) throws IOException {
BufferedImage img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
ImageIO.write(img, "JPG" , new File("C:/obraz.JPG"));
}

Jest ona w klasie DrawWndPane, czyli w tym panelu, z którego chcę pobierać obrazek. Tylko, ze jak potem otwieram obrazek, to jest on cały czarny...

W xródle była też metoda allPaint, ale jak ją dodaję, to mi się robie jakaś nieskończona pętla i jest StackOverflowException :/

PS. Przepraszam za moją upierdliwość :P

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