Problem z odrysowywaniem

0

Witam.
Prosze o pomoc w niniejszym kodzie. Jak nadpisuje metode paint w JPanel to po zaladowaniu do niego JButtona pojawia sie on dopiero jak na niego najade myszka. Tak samo jak zaladuje jakis obrazek to pojawia sie on dopiero jak okno przesune w lewa strone ekranu i mi ja wtedy repaintuje. Co jest nie tak?

public class Book {

/**
 * @param args
 */

public static void main(String[] args) {
	JFrame frame = new Ramka();

}

}
class Ramka extends JFrame
{
public static Image img;
public Ramka(){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setResizable(false);
setTitle(">>Wstawianie Zdjec<<");
setSize(700,700);
//Panele
//dzielimy na polowe
Container panel = getContentPane();
panel.setLayout(new GridLayout(0,2));

	//dzielimy na 2 gridy poziome lew strone
	JPanel lewy = new JPanel();
	lewy.setLayout(new GridLayout(2,0));
	panel.add(lewy);
	
	//lewa gora: dzielimy na 2 czesci gorna i dolna, dolna o wiele mniejsza dla buttona
	final JPanel gora = new BackgroundPanel();
	gora.setLayout(new BorderLayout());
	
	
	lewy.add(gora);
	//GridBagConstraints c = new GridBagConstraints();
	//c.gridwidth = GridBagConstraints.REMAINDER;
	
	//gora.add(new JLabel("gora"),c);
	//c.gridwidth = GridBagConstraints.REMAINDER;
	//c.fill = GridBagConstraints.NORTH;
	//c.fill=GridBagConstraints.EAST;
	final JButton cos = new JButton("Zaladuj zdjecie");
	gora.add(cos,BorderLayout.PAGE_END);
	gora.repaint();
	cos.repaint();
	cos.setVisible(true);
	cos.addActionListener(new ActionListener(){

		@Override
		public void actionPerformed(ActionEvent arg0) {
			if(arg0.getSource()==cos) 
			{
				//ladujemy JFileChoosera i pozniej ladujemy zdjecie
				JFileChooser chooser = new JFileChooser();
				chooser.showOpenDialog(null);
				//System.out.println(chooser.getSelectedFile().getPath());
				img = Toolkit.getDefaultToolkit().createImage(chooser.getSelectedFile().getPath());
				gora.repaint();
			}
			
		}
		
	});
	
	lewy.add(new JLabel("dol"));
	
	
	panel.add(new JLabel("tekst2"));
	
}

}
class BackgroundPanel extends JPanel
{
// The Image to store the background image in.

public void paint(Graphics g)
{
	super.paintComponent(g);
    // Draws the img to the BackgroundPanel.
	if(Ramka.img == null) {
		//rysujemy kwadracik i go zapelniamy color.darkgray
		Graphics2D g2 = (Graphics2D)g;
		Rectangle2D pros = new Rectangle2D.Double(0,0,2000,2000);
		g2.setPaint(Color.DARK_GRAY);
		g2.fill(pros);
		//g2.draw(pros);
	}
	else g.drawImage(Ramka.img, 0, 0, null);
	
}

}

0

Przenieś miejsce wywołania metody setVisible(true) albo tak:

public static void main(String[] args) {
                JFrame frame = new Ramka();
                frame.setVisible(true);

}

albo na koniec konstruktora. Chodzi o to że najpierw wyświetlasz ramkę a później dodajesz komponenty i coś najwyraźniej się wali.

Pozdrawiam

PS. Proszę następnym razem zamieszczaj kod między znacznikami bo strasznie lipnie się przegląda :p

0
flogum napisał(a)

Przenieś miejsce wywołania metody setVisible(true) albo tak:

public static void main(String[] args) {
                JFrame frame = new Ramka();
                frame.setVisible(true);

}

albo na koniec konstruktora. Chodzi o to że najpierw wyświetlasz ramkę a później dodajesz komponenty i coś najwyraźniej się wali.

Pozdrawiam

PS. Proszę następnym razem zamieszczaj kod między znacznikami bo strasznie lipnie się przegląda :p

Ok super. Nastepnym razem zamieszcze w znacznikach. Ale pomogles mi tylko w jednej kwestii. Kolejna jest taka ze jak zaladuje jakis obrazek badz zdjecie to dopiero mi je rysuje jak poruszam okienkiem tzn jak wezme je przeniose w lewa strone ekranu za obszar widoczny. Co jest z tym?

0

Jak zrobic zeby ten rysunek sie od razu pojawial a nie dopiero jak przerysowuje mi okno poprzez zmiane wielkosci?;/

Kod:

public class Book {

	/**
	 * @param args
	 */
	
	public static void main(String[] args) {
		JFrame frame = new Ramka();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setResizable(false);
		frame.setVisible(true);
		
	}

}
class Ramka extends JFrame
{
	public static Image img;
	public Ramka(){
		//setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		//setVisible(true);
		//setResizable(false);
		setTitle(">>Wstawianie Zdjec<<");
		setSize(700,700);
		//Panele
		//dzielimy na polowe
		Container panel = getContentPane();
		panel.setLayout(new GridLayout(0,2));
		
		//dzielimy na 2 gridy poziome lew strone
		final JPanel lewy = new JPanel();
		lewy.setLayout(new GridLayout(2,0));
		panel.add(lewy);
		
		//lewa gora: dzielimy na 2 czesci gorna i dolna, dolna o wiele mniejsza dla buttona
		final JPanel gora = new BackgroundPanel();
		gora.setLayout(new BorderLayout());
		
		
		lewy.add(gora);
		//GridBagConstraints c = new GridBagConstraints();
		//c.gridwidth = GridBagConstraints.REMAINDER;
		
		//gora.add(new JLabel("gora"),c);
		//c.gridwidth = GridBagConstraints.REMAINDER;
		//c.fill = GridBagConstraints.NORTH;
		//c.fill=GridBagConstraints.EAST;
		final JButton cos = new JButton("Zaladuj zdjecie");
		gora.add(cos,BorderLayout.PAGE_END);
		gora.repaint();
		cos.repaint();
		cos.setVisible(true);
		cos.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent arg0) {
				if(arg0.getSource()==cos) 
				{
					//ladujemy JFileChoosera i pozniej ladujemy zdjecie
					JFileChooser chooser = new JFileChooser();
					chooser.showOpenDialog(null);
					//System.out.println(chooser.getSelectedFile().getPath());
					img = Toolkit.getDefaultToolkit().createImage(chooser.getSelectedFile().getPath());
					
				}
				
			}
			
		});
		JPanel formularz = new JPanel();
		GridLayout xx = new GridLayout(5,2);
		formularz.setLayout(xx);
		xx.setHgap(1);
		xx.setVgap(1);
		
		lewy.add(formularz);
		JTextArea imie = new JTextArea();
		JTextArea nazwisko = new JTextArea();
		JTextArea adres = new JTextArea();
		JTextArea nick = new JTextArea();
		JLabel imie_d = new JLabel("Imie: ");
		JLabel nazwisko_d = new JLabel("Nazwisko: ");
		JLabel adres_d = new JLabel("Adres: ");
		JLabel nick_d = new JLabel("Nick: ");
		
		formularz.add(imie_d);
		formularz.add(imie);
		formularz.add(nazwisko_d);
		formularz.add(nazwisko);
		formularz.add(adres_d);
		formularz.add(adres);
		formularz.add(nick_d);
		formularz.add(nick);
		formularz.add(new JLabel(""));
		formularz.add(new JButton("Dodaj"));
		
		
		
		
		
		DefaultTableModel dtm=new DefaultTableModel();   //opisuje tabelę
		dtm.setColumnIdentifiers(columnNames);
        dtm.setColumnCount(4);        //kolumny
        dtm.setRowCount(40);             //wiersze
        JTable tabela=new JTable(dtm);     //tworzy tabelę na podstawie modelu
        tabela.setEnabled(false);
        
        tabela.addColumn(new TableColumn());    //przykładowe dodanie kolumny
        //tabela.setValueAt("Helo",1,1);        //ustawienie wartości w wybranym m-scu
        panel.add(new JScrollPane(tabela));
	}
	private String[] columnNames = {"Imie","Nazwisko","Adres","Nick"};
}
class BackgroundPanel extends JPanel
{
    // The Image to store the background image in.
   
	public void paintComponent(Graphics g) {
		
		if(Ramka.img == null) {
    		//rysujemy kwadracik i go zapelniamy color.darkgray
    		Graphics2D g2 = (Graphics2D)g;
    		Rectangle2D pros = new Rectangle2D.Double(0,0,2000,2000);
    		g2.setPaint(Color.DARK_GRAY);
    		g2.fill(pros);
    		//g2.draw(pros);
    	}
    	else  g.drawImage(Ramka.img, 0, 0, null);
		
		
		paintComponents(g);
		
	}
  
}
0

Dobra powiem tak odnośnie problemu problemu przycisku to nadal działa on nie do końca dobrze bo jak przykryjesz okno kilka razy to za którymś razem się nie odrysuje ale ten problem rozwiązuje dodanie jeszcze jednego panelu, po prostu żeby przycisk był na oddzielnym a rysunek na oddzielnym:

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;

import javax.swing.*;

public class Book {

        /**
         * @param args
         */
       
        public static void main(String[] args) {
                JFrame frame = new Ramka();
                frame.setVisible(true);

        }

}
class Ramka extends JFrame
{
        public static Image img;
        BackgroundPanel rysunek;
        
        public Ramka(){
        	setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setResizable(false);
            setTitle(">>Wstawianie Zdjec<<");
            setSize(700,700);
            
            Container panel = getContentPane();
            panel.setLayout(new GridLayout(0,2));
            
            JPanel lewy = new JPanel();
            lewy.setLayout(new GridLayout(2,0));
            panel.add(lewy);
            
            JPanel gora = new JPanel();
            gora.setLayout(new BorderLayout());
            lewy.add(gora);
            
            rysunek = new BackgroundPanel();
            gora.add(rysunek);
            
            JButton przycisk = new JButton("OK");
            przycisk.addActionListener(new ActionListener(){

				@Override
				public void actionPerformed(ActionEvent arg0) {
					// TODO Auto-generated method stub
                    JFileChooser chooser = new JFileChooser();
                    chooser.showOpenDialog(null);
                    img = Toolkit.getDefaultToolkit().getImage(chooser.getSelectedFile().getPath());
                    rysunek.repaint();
				}
            	
            });
            gora.add(przycisk, BorderLayout.SOUTH);
        }
}

class BackgroundPanel extends JPanel
{
    // The Image to store the background image in.
   
    public void paint(Graphics g)
    {
            super.paintComponent(g);
        // Draws the img to the BackgroundPanel.
            if(Ramka.img == null) {
                    //rysujemy kwadracik i go zapelniamy color.darkgray
                    Graphics2D g2 = (Graphics2D)g;
                    Rectangle2D pros = new Rectangle2D.Double(0,0,2000,2000);
                    g2.setPaint(Color.DARK_GRAY);
                    g2.fill(pros);
                    //g2.draw(pros);
            }
            else
            {
            	g.drawImage(Ramka.img, 0, 0, null);
            }
           
    }
} 

Co do problemu nie odrysowywania się rysunku to szczerze powiedziawszy, że szukałem i szukałem ale sam jestem początkującym javovcem :/ i nie mam pojęcia. Znalazłem coś takiego:

If the image has not yet been completely loaded, then drawImage returns false.
Sprawdziłem i faktycznie zwraca "false" czyli obrazek się nie ładuje plus to że paint nie jest wywoływana za każdym razem jak okienko jest pokazywane :/ Niestety ja tu nie pomogę trzeba zaczekać na specjalistów :p Z chęcią sam dowiem się o co chodzi. Pomogłem tyle ile mogłem :p

Pozdrawiam

0

Specjalistą nie jestem, ale mały tuning programu zrobiłem.
Kilka uwag:
1 Obiekt klasy JFileChooser powinno się tworzyć raz i zapamiętywać jako pole klasy. Wtedy użytkownik przy otwieraniu kolejnego zdjęcia startuje w katalogu w którym wybrał poprzednie.
2. Wypada sprawdzić czy użytkownik wybrał plik, czy też może wcisnął Cancel
3. Konstruując obiekt klasy JFileChooser można podać katalog startowy, domyślnie jest to katalog domowy użytkownika, ja tego nie lubię, stąd wywołanie konstruktora new JFileChooser("."); (katalog bieżący)

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;

import javax.swing.*;
import java.io.*;
import javax.imageio.*;

public class Book {

        /**
         * @param args
         */

        public static void main(String[] args) {
                JFrame frame = new Ramka();
                frame.setVisible(true);

        }

}
class Ramka extends JFrame
{
        public static Image img;
        private JFileChooser chooser = new JFileChooser(".");
        BackgroundPanel rysunek;

        public Ramka(){
                setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setResizable(false);
            setTitle(">>Wstawianie Zdjec<<");
            setSize(700,700);

            Container panel = getContentPane();
            panel.setLayout(new GridLayout(0,2));

            JPanel lewy = new JPanel();
            lewy.setLayout(new GridLayout(2,0));
            panel.add(lewy);

            JPanel gora = new JPanel();
            gora.setLayout(new BorderLayout());
            lewy.add(gora);

            rysunek = new BackgroundPanel();
            gora.add(rysunek);

            JButton przycisk = new JButton("OK");
            przycisk.addActionListener(new ActionListener(){

                                @Override
                                public void actionPerformed(ActionEvent arg0) {
                                        // TODO Auto-generated method stub

                    if(chooser.showOpenDialog(null)==JFileChooser.APPROVE_OPTION)
                    {
                        try
                        {
                            img=ImageIO.read(chooser.getSelectedFile());
                            rysunek.repaint();
                        }
                        catch(IOException e)
                        {
                            System.out.println(e);
                        }
                       //img = Toolkit.getDefaultToolkit().getImage(chooser.getSelectedFile().getPath());

                    }
                                }

            });
            gora.add(przycisk, BorderLayout.SOUTH);
           //żeby okienko było na środku monitora
            setLocationRelativeTo(null);
            //zeby chooser pokazywał tylko pliki graficzne       
            chooser.setFileFilter(new javax.swing.filechooser.FileFilter()
            {
                public boolean accept(File f)
                {
                    String name=f.getName().toLowerCase();
                    return name.endsWith(".gif") || name.endsWith(".jpg") || name.endsWith(".jpeg")
                       || name.endsWith(".png") || f.isDirectory();
               }
               public String getDescription()
               {
                   return "Pliki graficzne";
               }
           });
        }
}

class BackgroundPanel extends JPanel
{
    // The Image to store the background image in.
   
    public void paint(Graphics g)
    {
            super.paintComponent(g);
        // Draws the img to the BackgroundPanel.
            if(Ramka.img == null) {
                    //rysujemy kwadracik i go zapelniamy color.darkgray
                    Graphics2D g2 = (Graphics2D)g;
                    Rectangle2D pros = new Rectangle2D.Double(0,0,2000,2000);
                    g2.setPaint(Color.DARK_GRAY);
                    g2.fill(pros);
                    //g2.draw(pros);
            }
            else
            {
                    g.drawImage(Ramka.img, 0, 0, null);
            }
           
    }
}
0

Faktycznie teraz działa choć nie mam zielonego pojęcia jak ta zmiana ma się do tego, że wcześniej metoda "paint" wczytywała plik graficzny dopiero za którymś wywołaniem a teraz robi to od razu. Jakbyś mógł to wyjaśnić byłbym wdzięczny. Chciałbym zrozumieć :)

Pozdrawiam

EDIT: Cofam pytanie okazuje się, że:

ImageIO.read(chooser.getSelectedFile());

Ta linia załatwia wszystko. :)

Pozdrawiam

0

Ja też bym chciał zrozumieć ;-) .
Wygląda, że metoda (której nie używam):

Toolkit.getDefaultToolkit().getImage(chooser.getSelectedFile().getPath());

jest bardzo wolna.

0

Albo

ImageIO.read(chooser.getSelectedFile());

Czeka na wczytanie pliku. Ale nie mogę nic o tym wygooglować :)

Pozdrawiam

0

Widze ze forum jest aktywne :) No ja to pod koniec juz nie chcialem sie miotac z tym nadpisywanie JPanela wiec wsadzilem tam JLabela w to miejsce i dziala extra :) no a z tym repaintowanie to dziwne ;/

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