Kłopoty z przeglądarką

0

Witam serdecznie forumowiczów! Piszę prostą przeglądarkę plików grafiki rastrowej, kłopot sprawiają mi 2 sprawy:

  1. Obraz ładuje mi sie jeden na drugim (załączam zrzut ekranu),
  2. Chcę dodać możliwość zmiany wartości RGB, stworzyłem JSlider, lecz nie mam pojęcia, jak "podpiąć" go do mojego obrazu.

Oto kod.

class okno_glowne extends JFrame implements ActionListener{
   public static void main(String[] args){
     java.awt.EventQueue.invokeLater(new Runnable(){
     public void run(){
     new okno_glowne().setVisible(true);
     }
     });
} 
    
    
   private JPanel rozklad;
   private JLabel obszar_rysowania;
   private JScrollPane suwaki;
   
   private JSlider rgb;
  
   private JMenuBar pasek; 
   private JMenuItem otworzp;
   private JMenuItem rgbn;
   private JMenu plik_,obraz_;
   
   private File plik1;
   
   private BufferedImage obraz;
   private String nazwa_pliku,sciezka;
   
public okno_glowne(){
   stworz_okno(); 
 }

public void stworz_okno(){
   setVisible(true);
   setSize(1000,600);
   setTitle("Przeglądarka plików graficznych 1.4 alfa");
   setResizable(true);
   setLocationRelativeTo(null);
   setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   
   rozklad=new JPanel();

   pasek=new JMenuBar();
   setJMenuBar(pasek);  

        plik_=new JMenu("Plik");
        pasek.add(plik_);
        
        otworzp=new JMenuItem("Otwórz");
        otworzp.addActionListener(this);
        plik_.add(otworzp);
         
            obraz_=new JMenu("Obraz");
            pasek.add(obraz_);
            
            rgbn=new JMenuItem("rgb");
            rgbn.addActionListener(this);
            obraz_.add(rgbn); 
            rgbn.setEnabled(false);

}            

    @Override
    public void actionPerformed(ActionEvent e){
        try {
            String polecenie=e.getActionCommand();

            if(polecenie.equals("Otwórz")) otworz();
            else if(polecenie.equals("rgb")){
                rgb r=new rgb(this,false);
            }

        } catch (IOException ex) {
            Logger.getLogger(okno_glowne.class.getName()).log(Level.SEVERE, null, ex);
        }
}  

 public BufferedImage rysuj(){  
     obszar_rysowania=new JLabel();
     obszar_rysowania.setHorizontalAlignment(JLabel.CENTER);
     obszar_rysowania.setVerticalAlignment(JLabel.CENTER);
     ImageIcon ii=new ImageIcon(obraz);
     obszar_rysowania.setIcon(ii);
     suwaki=new JScrollPane(obszar_rysowania);
     this.add(suwaki);
     revalidate();  
     repaint(1000); 
     return obraz;  
 }


public void otworz() throws IOException{
      JFileChooser otworz=new JFileChooser("//");
      FileNameExtensionFilter rastrowa=new FileNameExtensionFilter("Pliki grafiki rastrowej(.jpeg,.png.,gif...)", "jpeg","jpg", "gif","png","bmp");
      otworz.setFileFilter(rastrowa);
      int a=otworz.showOpenDialog(null);
      
      if(a==JFileChooser.APPROVE_OPTION){
      nazwa_pliku=otworz.getSelectedFile().getAbsolutePath();
      String roz=nazwa_pliku.substring(nazwa_pliku.lastIndexOf('.')+1);
      plik1=otworz.getSelectedFile();
      obraz=ImageIO.read(plik1);          
      rysuj();
      
      File plik=new File(nazwa_pliku);
      String nazwa_kat=plik.getParent();
      
      System.out.print(nazwa_kat+"/");
      

        rgbn.setEnabled(true);
     }
 
}
}
/////////////////////////////////////////

   public class rgb extends JDialog implements ActionListener,ChangeListener{
    JButton zatwierdz,anuluj;
    JSlider suwaczekR,suwaczekG,suwaczekB,suwaczekA;
    JLabel r,g,b,a;
    JTextField poleR,poleG,poleB,poleA;
    JPanel roz_okienka;
    
   public rgb(java.awt.Frame parent, boolean modal){
        super(parent,modal);
        stworz_okienko();
   } 
    
   public void stworz_okienko(){
       
       this.setVisible(true);
       this.setTitle("Skala szarości");
       this.setResizable(false);
       this.setSize(700,700);
       this.setLocationRelativeTo(null);
       
       roz_okienka=new JPanel();

            zatwierdz=new JButton("Zatwiedz zmiany");
            zatwierdz.addActionListener(this);

                r=new JLabel("R");
                g=new JLabel("G");
                b=new JLabel("B");
                a=new JLabel("A");
                    
                    poleR=new JTextField(3);
                    poleR.addActionListener(this);
                    poleG=new JTextField(3);
                    poleG.addActionListener(this);
                    poleB=new JTextField(3);
                    poleB.addActionListener(this);
                    poleA=new JTextField(3);
                    poleA.addActionListener(this);
                           
                        suwaczekR=new JSlider(0,255,0);
                        suwaczekR.setPaintLabels(true);
                        suwaczekR.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
                        suwaczekR.addChangeListener(this);

                        suwaczekG=new JSlider(0,255,0);
                        suwaczekG.setPaintLabels(true);
                        suwaczekG.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
                        suwaczekG.addChangeListener(this);

                        suwaczekB=new JSlider(0,255,0);     
                        suwaczekB.setPaintLabels(true);
                        suwaczekB.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
                        suwaczekB.addChangeListener(this);

                        suwaczekA=new JSlider(0,255,0);
                      //  suwaczekA.setMajorTickSpacing(255);
                    //    suwaczekA.setMinorTickSpacing(1);
                     //   suwaczekA.setPaintTicks(true);
                        suwaczekA.setPaintLabels(true);
                        suwaczekA.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
                        suwaczekA.addChangeListener(this);

                            GroupLayout gr=new GroupLayout(roz_okienka);
                            roz_okienka.setLayout(gr);
                            gr.setAutoCreateGaps(true);
                            gr.setAutoCreateContainerGaps(true);

                            GroupLayout.SequentialGroup na_szer=gr.createSequentialGroup();  
                            GroupLayout.SequentialGroup na_wys=gr.createSequentialGroup();  

                            GroupLayout.ParallelGroup szerpgr1=gr.createParallelGroup(GroupLayout.Alignment.LEADING);  
                            GroupLayout.ParallelGroup szerpgr2=gr.createParallelGroup(GroupLayout.Alignment.LEADING);
                            GroupLayout.ParallelGroup szerpgr3=gr.createParallelGroup(GroupLayout.Alignment.LEADING);

                            szerpgr1.addComponent(r);
                            szerpgr2.addComponent(suwaczekR);
                            szerpgr3.addComponent(poleR);
                            szerpgr1.addComponent(g);
                            szerpgr2.addComponent(suwaczekG);
                            szerpgr3.addComponent(poleG);
                            szerpgr1.addComponent(b);
                            szerpgr2.addComponent(suwaczekB);
                            szerpgr3.addComponent(poleB);
                            szerpgr1.addComponent(a);
                            szerpgr2.addComponent(suwaczekA);
                            szerpgr3.addComponent(poleA);
                            szerpgr2.addComponent(zatwierdz);

                            na_szer.addGroup(szerpgr1);  
                            na_szer.addGroup(szerpgr2); 
                            na_szer.addGroup(szerpgr3); 

                                GroupLayout.ParallelGroup wyspgr1=gr.createParallelGroup(GroupLayout.Alignment.BASELINE);
                                GroupLayout.ParallelGroup wyspgr2=gr.createParallelGroup(GroupLayout.Alignment.BASELINE);
                                GroupLayout.ParallelGroup wyspgr3=gr.createParallelGroup(GroupLayout.Alignment.BASELINE);
                                GroupLayout.ParallelGroup wyspgr4=gr.createParallelGroup(GroupLayout.Alignment.BASELINE);
                                GroupLayout.ParallelGroup wyspgr5=gr.createParallelGroup(GroupLayout.Alignment.CENTER);
                                wyspgr1.addComponent(r);
                                wyspgr1.addComponent(suwaczekR);
                                wyspgr1.addComponent(poleR);
                                wyspgr2.addComponent(g);
                                wyspgr2.addComponent(suwaczekG);
                                wyspgr2.addComponent(poleG);
                                wyspgr3.addComponent(b);
                                wyspgr3.addComponent(suwaczekB);
                                wyspgr3.addComponent(poleB);
                                wyspgr4.addComponent(a);
                                wyspgr4.addComponent(suwaczekA);
                                wyspgr4.addComponent(poleA);
                                wyspgr5.addComponent(zatwierdz);

                                na_wys.addGroup(wyspgr1);
                                na_wys.addGroup(wyspgr2);
                                na_wys.addGroup(wyspgr3);
                                na_wys.addGroup(wyspgr4);
                                na_wys.addGroup(wyspgr5);

                                    gr.setHorizontalGroup(na_szer);
                                    gr.setVerticalGroup(na_wys);

                    add(roz_okienka);
                    pack();                                     
   }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object zrodlo=e.getSource();
        int wartA=Integer.parseInt(poleA.getText());
        
        if(zrodlo==poleA){
           if(wartA>255) suwaczekA.setValue(255);         
           else if(wartA<0) suwaczekA.setValue(0);
           else suwaczekA.setValue(wartA);
        }
    }

    @Override
    public void stateChanged(ChangeEvent e) {
        Object zrodlo=e.getSource();
        
        if(zrodlo==suwaczekA){
            if (!suwaczekA.getValueIsAdjusting()) {
              int wartosc=suwaczekA.getValue(); 
              poleA.setText(Integer.toString(wartosc));
              zmien_A(wartosc);
            }
        }  
    }
  
    private void zmien_A(int wartosc){
        okno_glowne og=new okno_glowne();
        BufferedImage img=og.rysuj();

        wartosc %= 0xff; 
        for(int cx=0;cx<img.getWidth();cx++){          
            for(int cy=0;cy<img.getHeight();cy++){ 
                int color=img.getRGB(cx, cy);
                int mc=(wartosc << 24) | 0x00ffffff;
                int newcolor = color & mc;
                img.setRGB(cx, cy, newcolor);            
            }
        } 
    }
}
0

A nie możesz tego ułożyć jak normalny człowiek w jakimś design'erze?

0

@szopenfx Jeżeli chodzi o designer typu nedbeans to niestety, ale prowadzący zajęcia zabronił nam uzywać tego. Poza tym, wole napisac kod :]

0

Wychowany na Delphi uznaje takie podejście jako oczywistość, natomiast jeśli chodzi o programistów C++, JAVA to zauważyłem tendencję do pisania UI co jest nieefektywne, wprowadza więcej problemów z ogarnięciem takiego kodu a to samo można osiągnąć przy użyciu wizualnych narzędzi. Tym bardziej, że mamy wpływ na dynamiczne kontenery, które poukładają sobie komponenty wg. własnej hierarchii uzależnionej od wielkości okna, przeciągania itp. "wyobrażenie" sobie tego jest co najmniej trudne i jak widać na tym przykładzie karkołomne. Rozumiałbym takie podejście jeszcze kilka lat temu gdy o dobre IDE było trudno, ale teraz zarówno do JAVY jak i pozostałych są odpowiednie tool'e. Od początku mojego kodzenia nie musiałem zaglądać w kod wygenerowany przez automat, żeby coś "ulepszyć". Co do prowadzącego zajęcia też miałem podobnie podczas nauki Qt i do tej pory nie mam pojęcia czego miało mnie to niby nauczyć - widać myślenie się tak szybko nie zmienia, ale trudno jak mus to mus.
Zaraz pewnie padnie argument za tym, że "pisanie" UI poprawia szybkość wykonywania się programu - pewnie tak jest, na pewno czyste WinApi daje lepszą kontrolę, ale jest o wiele trudniej zapanować nad przypadkowymi błędami, natomiast nie jestem przekonany czy ma to sens w przypadku JAVA, może @Wibowit się na ten temat wypowie bo z tego co widzę na co dzień w niej rzeźbi.
Co do wskazania błędów w powyższym kodzie niestety nie pomogę.

0

@szopenfx, widziałeś kiedyś kod wygenerowany przez designera NetBeans? Raczej nie, bo zdanie

wprowadza więcej problemów z ogarnięciem takiego kodu
nie przeszło by Ci przez gardło.

0

Jak pisałem własne programy z GUI Swingowym to z reguły używałem kreatora z NetBeansa. Nie jest perfekcyjny, ale do małych programów w zupełności wystarczający. Poza tym nie jara mnie klepanie setek linijek by stworzyć GUI :p

Co do ogólnej tendencji pisania layoutów - to chyba jest powszechne jeśli chodzi o klepanie dużych aplikacji (grubych klientów). Jeśli w aplikacji jest np 100 podobnie wyglądających okien to i tak łatwiej jest zaklepać to okno w jednej klasie, a w 100 następnych stworzyć go w kilku linijkach niż używać kreatora graficznego.

0

Designery nie powinny generować kodu programu, bo to bez sensu - taki kod jest okropny. Powinny za to generować coś w stylu xml, któro jest później parsowane i zamieniane na layout programu. (coś jak robi designer androidowy)

0

Witam ponownie. Czy ktoś może zajrzał do mojego kodu? Widzę, że odbyła się tu tylko mała dyskusja nie na temat. :)

0
Kerai napisał(a):

Designery nie powinny generować kodu programu, bo to bez sensu - taki kod jest okropny.
Designer z Eclipse generuje całkiem ładny kod.

0

Ja spojrzałem, ale jak zobaczyłem tę metodę (chyba kluczową dla Twojego problemu)

 public BufferedImage rysuj(){  
     obszar_rysowania=new JLabel();
     obszar_rysowania.setHorizontalAlignment(JLabel.CENTER);
     obszar_rysowania.setVerticalAlignment(JLabel.CENTER);
     ImageIcon ii=new ImageIcon(obraz);
     obszar_rysowania.setIcon(ii);
     suwaki=new JScrollPane(obszar_rysowania);
     this.add(suwaki);
     revalidate();  
     repaint(1000); 
     return obraz;
} 

to zrezygnowałem z dalszej lektury kodu. Nazwa metody ma niewiele wspólnego z tym co metoda robi. Metoda zwraca obraz, którego nie tworzy, on już istniał przed wywołaniem metody. Wiersz

this.add(suwaki);

dodaje do okna nowy ScrollPane z obrazkiem, a nigdzie nie widać usunięcia poprzedniego obrazka.

0

Jest jeszcze jedna metoda, której kiedys używałem, lecz problem polega tutaj na nieodświeżaniu rozmiaru mojego JScrollPane (za każdym razem posiadał on tę samą wielkość od momentu otwarcia pierwszego obrazka).

public void rysuj(){  
     obszar_rysowania=new JPanel(new BorderLayout()){
            protected void paintComponent(Graphics g){
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g;
                g2d.drawImage(obraz, 0, 0, null);             
            }         
     };   
     obszar_rysowania.setPreferredSize(new Dimension(obraz.getWidth(),obraz.getHeight()));
     suwaki=new JScrollPane(obszar_rysowania);
    // suwaki.setPreferredSize(new Dimension(obraz.getWidth(),obraz.getHeight()));
     suwaki.setViewportView(obszar_rysowania);
     this.add(suwaki);
     revalidate();  
     repaint();    
}

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