Ustawianie FocusListener dla kilku JInternalFrame

0

Witam
Pisze program Notepad z opcja Open i kilkoma JInternalFrame.
Posiadam klase ktora tworzy mi moje JInternalFrame w JDesktopPane
Kazde JInternalFrame posiada JTextArea rowniez tworzone w tejze klasie.
Pytanie jak zrobic aby program wiedzial ktore JIternalFrame jest aktualnie aktywne
Bo jak na razie zawsze wczytuje mi plik do ostatnio utworzonego JInternalFrame
Moja klasa

 class MyInternalFrame extends JInternalFrame implements FocusListener {

	  static final int xPosition = 30, yPosition = 30;	  
	  public MyInternalFrame() {
	   super("Okno #" + (++frameNumber), true,true,true,true);
	   setSize(300, 300);	   
	   text = new JTextArea();
	   text.addFocusListener(this);	   
	   setLocation(xPosition * frameNumber, yPosition
	     * frameNumber);
	  }
	@Override
	public void focusGained(FocusEvent e) {
									
			}
	@Override
	public void focusLost(FocusEvent e) {
		
		
	}
Nie dokonca mam pojecie jak sie zabrac za ustawianie Focusa
i czy to jest problem focusa za wszelkie podpowiedzi bede wdzieczny.
0

A może byś zdradził w jaki sposób wczytujesz plik do JTextArea? Tzn. co musi zrobić użytkownik by się zaczęło wpisywanie?
W JDesktopPane masz metodę getSelectedFrame(). Nie mogę zrozumieć w czym tu może być trudność.

0

Juz daje wiecej informacji Open otwiera dowolny plik txt z dysku
Oto co udalo mi sie do tej pory stworzyc :

public class Notepad extends JFrame {

	
	JMenuItem copy,cut,paste;
	public JTextArea text;
	static int frameNumber = 0;
	static int tabNumber =1;
	JTabbedPane tab;
	private JFileChooser choose = new JFileChooser(System.getProperty("user.dir"));
	private JDesktopPane desktop;
	private String currentFile = "Untitled";
	JInternalFrame frame,win;
	
	
	Notepad(){
								
		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);

                      JMenu file = new JMenu("File");
		menuBar.add(file);
		
				
				
		newF.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_N);
		KeyStroke newFkey = KeyStroke.getKeyStroke("control N");
		newF.putValue(Action.ACCELERATOR_KEY, newFkey);
		JMenuItem newFItem =new JMenuItem(newF);
		newFItem.setIcon(null);
		
		open.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_O);
		KeyStroke openkey = KeyStroke.getKeyStroke("control O");
		open.putValue(Action.ACCELERATOR_KEY, openkey);
		JMenuItem openItem =new JMenuItem(open);
		openItem.setIcon(null);

		file.add(newFItem);
		file.add(openItem);
		tab = new JTabbedPane();
		add(tab, BorderLayout.CENTER);
		
		
		makeTab();

private void read(String fileName) {
		try {
			FileReader f = new FileReader(fileName);			
			text.read(f,null);
			f.close();
			currentFile = fileName;			
			setTitle(currentFile);
						
		}
		catch(IOException e) {
			
			JOptionPane.showMessageDialog(this,"Brak pliku "+fileName);
		}
	}

public void makeTab(){//Tworzy nowy desktop
	
		MyInternalFrame frame = new MyInternalFrame();
		frame.setVisible(true);
		frame.getContentPane().add(text);
	           desktop = new JDesktopPane();	      
	           desktop.add(frame);
	      try {
		    	 frame.setSelected(true);
		    	 } catch (PropertyVetoException pve) {
		    	 }    
	    pack();
	    setSize(2000, 2000);
	    setVisible(true);
	    tab.add("WorkSpace :"+tabNumber,getContentPane().add(desktop));
	    	tabNumber++; 
	    	
		
		    setSize(500, 500);
		    setVisible(true);
	    }
Action newF = new AbstractAction("New",new ImageIcon("new.gif")) {	//element Action tworzy dodatkowe JInternalFrame w juz otwartym Desktopie
		public void actionPerformed(ActionEvent e) {
			MyInternalFrame win = new MyInternalFrame();
			win.setVisible(true);			
			desktop.add(win);
		    win.setVisible(true);		    					    		    
		    win.getContentPane().add(text);	    
	
		    try {
		    	 win.setSelected(true);
		    	 } catch (PropertyVetoException pve) {
		    	 }
		}
	};

Action open = new AbstractAction("Open",new ImageIcon("open.gif")) {	//	
		public void actionPerformed(ActionEvent e) {
			if(choose.showOpenDialog(null)==JFileChooser.APPROVE_OPTION) {
				read(choose.getSelectedFile().getAbsolutePath());
											
			
			}					
		}
	};

private static void Show() {
		Zad51 aplikacja = new Zad51();
		aplikacja.setTitle("Prosty edytor " );
		aplikacja.setVisible(true);	   
		aplikacja.setSize(500, 500);
		//aplikacja.pack();
		aplikacja.setLocationRelativeTo(null);
		aplikacja.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
  public static void main(String[] args) {

	  {
			SwingUtilities.invokeLater(new Runnable() {

				public void run() {
					Show();
				}
			});
		}

}
  class MyInternalFrame extends JInternalFrame implements FocusListener {
	  
	  static final int xPosition = 30, yPosition = 30;	  
	  public MyInternalFrame() {
	   super("Okno #" + (++frameNumber), true,true,true,true);
	   setSize(300, 300);	   
	   text = new JTextArea();
	   text.addFocusListener(this);	   
	   setLocation(xPosition * frameNumber, yPosition
	     * frameNumber);
	  }
	@Override
	public void focusGained(FocusEvent e) {
									
			}
	@Override
	public void focusLost(FocusEvent e) {
		
		
	}
		
	 }
  
}
0

Ty nie masz tylu pól tekstowych ile jest ramek wewnętrznych, Ty masz jedno pole tekstowe.

0

A maszjakis pomysl jak to przerobic bo ja musze przyznac
nie bardzo juz teraz lapie w jaki sposob mialbym je indeksowac.

0

Pole text powinno się znajdować w klasie MyInternalFrame, a nie w klasie Notepad, a odczytanie pliku powinno wyglądać tak:

                        FileReader f = new FileReader(fileName);
                        getSelectedFrame().text.read(f,null);
0

Sorry ze dalej cie mecze ale jak przerzuce pole text do klasy MyInternalFrame to pole to nie bedzie widoczne w klasie Notepad() a tam go nadal uzywam
I jeszcze pytanie co do metody GetSelectedFrame czy dobrze ją robie

public JInternalFrame getSelectedFrame(){
		
		return desktop.getSelectedFrame();
	}
0

Jak umieścisz pole text w klasie Notepad, to masz w programie jedno pole tekstowe. Rozumiem, że chcesz mieć kilka(naście) i edytowaćwać w nich różne pliki. Z klasy Notepad możesz się odwoływać do tych pól przez getSelectedFrame().text (jeśli pole nie będzie private), lub getSelectedFrame().getText() (jeśli napiszesz sobie settera).

0

Może ja cos przekombinowałem bo ciagle mi tego pola nie widzi
Moja klasa MyInternalFrames

 public class MyInternalFrame extends JInternalFrame implements FocusListener {

             public JTextArea text;

	  static final int xPosition = 30, yPosition = 30;	  
	  public MyInternalFrame() {
		  
	   super("Okno #" + (++frameNumber), true,true,true,true);
	    
	   setSize(300, 300);	   
	   text = new JTextArea();
	   text.addFocusListener(this);	   
	   setLocation(xPosition * frameNumber, yPosition
	     * frameNumber);
	  }
	@Override
	public void focusGained(FocusEvent e) {
									
			}
	@Override
	public void focusLost(FocusEvent e) {
				
	}				
	 }
no i moja metoda read

public void read(String fileName) {
		try {
			FileReader f = new FileReader(fileName);			
			getSelectedFrame().text.read(f,null);
			f.close();
			currentFile = fileName;			
			setTitle(currentFile);
						
		}
		catch(IOException e) {
			
			JOptionPane.showMessageDialog(this,"Brak pliku "+fileName);
		}
	}

a co do mojej metody getSelectedFrame jest ok??
dzieki za cierpliwość co mi przyszlo na stare lata javy sie uczyc:)

0

getSelectedFrame zwraca instancję klasy JInternalFrame, a ta klasa nie posiada pola text. Zapewne w twoim przypadku zwraca konkretnie instancję klasy MyInternalFrame, więc musisz sobie to sprawdzić i zrobić rzutowanie. Przykładowy kod:

public class Main {
    
    public static void sprawdź(Number liczba) {
        if (liczba instanceof Double) {
            Double liczbaZmiennoprzecinkowa = (Double) liczba;
            System.out.println("To jest konkretnie liczba zmiennoprzecinkowa: " + 
                    liczbaZmiennoprzecinkowa);
        } else {
            System.out.println("Nie, to nie jest konkretnie liczba typu Double.");
        }
    }
    
    public static void main(String[] args) {
        Number liczba = 5.;
        sprawdź(liczba);
        liczba = 5;
        sprawdź(liczba);
    }
}
0

To teraz to mnie juz kompletnie rozlozylo :)
Wydawało mi sie ze jesli pole jest typu public to powinno byc widoczen w klasie nadrzednej
robie tak w klasie MyInternalFrame tworze metode

public JTextArea getTxt()
		{
		    return text;
		}


a w metodzie read

((MyInternalFrame) getSelectedFrame()).getTxt().read(f,null);

niby wszystko fajnie ale wywala mi dziwny blad

at java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$000(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)

0

No, uciąłeś stacktrace w połowie pewnie i nawet nie podałeś nazwy wyjątku.

0

Sory mam malego laptopa nie zauważylem

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at zad51.Zad51.getSelectedFrame(zad51.java:176)
	at zad51.Zad51.makeTab(zad51.java:184)
	at zad51.Zad51.<init>(zad51.java:126)
	at zad51.Zad51.Show(zad51.java:263)
	at zad51.Zad51.access$2(zad51.java:262)
	at zad51.Zad51$7.run(zad51.java:277)
	at java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$000(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)

zad51=Notepad

0

Nazwa wyjątku mówi sama za siebie. Nie wiem jak działa ta metoda, tzn kiedy zwraca nulla. Ja bym skorzystał z tego FocusListenera, tzn stworzył instancję FocusListnera, trzymał w głównym frame i dodał tego listenera do wszystkich JInternalFrame za pomocą addFocusListener (oczywiście do każdego JInternalFrame z osobna). Wtedy z FocusEvent z metody focusGained możnaby wyciągnąć ostatnio aktywowanego JInternalFrame'a. Tak myślę, nie wiem czy by to zadziałało.

0

Może i masz racje ale moje umiejętnosci programistyczne sa troche za małe na takie manewry :)

Kolega "bo"
proponowal taka droge moze to by zdalo rezulata moze ktos by sie jeszcze wypowiedzial

Jak umieścisz pole text w klasie Notepad, to masz w programie jedno pole tekstowe. Rozumiem, że chcesz mieć kilka(naście) i edytowaćwać w nich różne pliki. Z klasy Notepad możesz się odwoływać do tych pól przez getSelectedFrame().text (jeśli pole nie będzie private), lub getSelectedFrame().getText() (jeśli napiszesz sobie settera).

  public class MyInternalFrame extends JInternalFrame implements FocusListener {
      public JTextArea text;
	  static final int xPosition = 30, yPosition = 30;	  
	  public MyInternalFrame() {
		  
	   super("Okno #" + (++frameNumber), true,true,true,true);
	    
	   setSize(300, 300);	   
	   text = new JTextArea();
	   text.addFocusListener(this);	   
	   setLocation(xPosition * frameNumber, yPosition
	     * frameNumber);
	  }
	
	@Override
	public void focusGained(FocusEvent e) {
									
			}
	@Override
	public void focusLost(FocusEvent e) {
	}

Teraz jak sprawic aby
ta metoda z innej classy widziala pole text

public void makeTab(){//Tworzy nowy desktop
	
		MyInternalFrame frame = new MyInternalFrame();
		frame.setVisible(true);
		
		
		frame.getContentPane().add(text);
	      desktop = new JDesktopPane();
	      
	      desktop.add(frame);
	      try {
		    	 frame.setSelected(true);
		    	 } catch (PropertyVetoException pve) {
		    	 }    
	  
	    setVisible(true);
	    tab.add("WorkSpace :"+tabNumber,getContentPane().add(desktop));
	    	
	    	
		
		    setSize(500, 500);
		    setVisible(true);
	    }
0

To może inaczej. Niech MyInternalFrame przyjmuje Zad51 w konstruktorze i go zapamiętuje. Zad51 niech ma pole lastFocusedTextArea (albo coś w ten deseń) typu MyInternalFrame. W ciele metody focusGained niech instancja MyInthernalFrame ustawi pole lastFocusedTextArea z rodzica (przekazanego w konstruktorze) na siebie. Powinno działać.

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