2012-04-04 3 views
1

У меня проблема с JTabbedPane, поскольку содержимое отдельных вкладок не отображается (каждый раз, когда я нажимаю новую вкладку, активная вкладка меняет, а содержимое не делает, поэтому я см. тот же контент независимо от того, какая вкладка выбрана.).JTabbedPane не меняет содержимое вкладки

Я пытаюсь написать IDE для своего собственного языка программирования, но никогда раньше не работал с JTabbedPane. Моя панель с вкладками состоит из JEditTextArea (пользовательский компонент), размещенного в JScrollPanes. Вот ответственный класс

package tide.editor; 

import javax.swing.*; 

import javax.swing.filechooser.FileNameExtensionFilter; 

import java.awt.Toolkit; 
import java.awt.BorderLayout; 
import java.awt.event.ActionListener; 
import java.awt.event.ActionEvent; 
import java.io.File; 
import java.io.FileNotFoundException; 
import java.util.ArrayList; 
import java.util.Scanner; 

import org.syntax.jedit.*; 
import org.syntax.jedit.tokenmarker.*; 

@SuppressWarnings("serial") 
public class Editor extends JFrame implements ActionListener { 

//Version ID 
final static String VERSION = "0.01a"; 

//The editor pane houses the JTabbedPane that allows for code editing 
//JPanel editorPane; 

JTabbedPane tabbedPanel; 

//The JTextPanes hold the source for currently open programs 
ArrayList<JEditTextArea> textPanes; 

//The toolbar that allows for quick opening, saving, compiling etc 
JToolBar toolBar; 

//Buttons for the toolbar 
JButton newButton, openButton, saveButton, compileButton, runButton; 


public Editor() 
{ 
    super("tIDE v" + VERSION); 
    setSize(Toolkit.getDefaultToolkit().getScreenSize()); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setLayout(new BorderLayout()); 
    init(); 
    setVisible(true); 
    textPanes.get(0).requestFocus(); 
} 

public void init() 
{ 
    //Initialise toolbar 
    toolBar = new JToolBar(); 
    toolBar.setFloatable(false); 

    newButton = new JButton("New"); 
    newButton.addActionListener(this); 
    openButton = new JButton("Open"); 
    openButton.addActionListener(this); 
    saveButton = new JButton("Save"); 
    saveButton.addActionListener(this); 
    compileButton = new JButton("Compile"); 
    compileButton.addActionListener(this); 
    runButton = new JButton("Run"); 
    runButton.addActionListener(this); 

    toolBar.add(newButton); 
    toolBar.add(openButton); 
    toolBar.add(saveButton); 
    toolBar.add(compileButton); 
    toolBar.add(runButton); 


    tabbedPanel = new JTabbedPane(); 

    textPanes = new ArrayList<JEditTextArea>(); 

    JEditTextArea initialProgram = createTextArea("program.t"); 

     tabbedPanel.addTab(initialProgram.getName(), new JScrollPane(initialProgram)); 


    getContentPane().add(tabbedPanel, BorderLayout.CENTER); 
    add(toolBar, BorderLayout.NORTH); 
} 

public static void main(String[] args) 
{ 
java.awt.EventQueue.invokeLater(new Runnable() { 

    @Override 
    public void run() { 
     new Editor(); 
    } 
}); 

} 

JEditTextArea createTextArea(String name) 
{ 
    JEditTextArea editPane = new JEditTextArea(name); 
    editPane.setTokenMarker(new TTokenMarker()); 

    textPanes.add(editPane); 

    return editPane; 
} 

public void actionPerformed(ActionEvent e) { 

    if (e.getSource() == newButton) 
    { 
     String filename = "program2"; 
     boolean fileExists = true; 

     //Ensures that no duplicate files are created 
     while (fileExists) 
     { 
     fileExists = false; 
     //Get new file name from user 
     filename = JOptionPane.showInputDialog(null, "Enter a name for the file", "program.t"); 

     //Cancel was clicked in the new file dialog 
     if (filename == null) 
      return; 

      for (JEditTextArea panes: textPanes) 
      { 
       if (panes.getName().equals(filename) || panes.getName().equals(filename.concat(".t")) || panes.getName().concat(".t").equals(filename)) 
        fileExists = true; 
      } 
     } 

     //add extension if it is missing 
     if(!filename.endsWith(".t")) 
      filename = filename.concat(".t"); 

     //Add the new "file" to the editor window in a new tab 
     tabbedPanel.addTab(filename, new JScrollPane(createTextArea(filename))); 
     tabbedPanel.setSelectedIndex(tabbedPanel.getSelectedIndex()+1); 
    } 

    if (e.getSource() == openButton) 
    { 
     File f = null; 


     JFileChooser fileChooser = new JFileChooser(); 
     fileChooser.setDialogTitle("Choose target file location"); 
     fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); 
     fileChooser.setAcceptAllFileFilterUsed(false); 
     FileNameExtensionFilter filter = new FileNameExtensionFilter(
       "t source or bytecode(.t, .tbc)", "t", "tbc"); 

     fileChooser.setFileFilter(filter); 

     if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) 
     { 
      f = fileChooser.getSelectedFile(); 
     } 

     //Cancel button was clicked on the open file dialog 
     if (f == null) 
      return; 

     //Load the contents of the selected file into the editor 
     else 
     { 
      JEditTextArea textArea = null; 
      StringBuilder inputText = null; 

      try { 
       Scanner sc = new Scanner(f); 

       //Add a new text area to the editor 
       textArea = createTextArea(f.getName()); 
       tabbedPanel.add(new JScrollPane(textArea), textArea.getName()); 

       //The newly added tab is set as the active tab 
       tabbedPanel.setSelectedIndex(tabbedPanel.getTabCount()-1); 
       textArea.requestFocus(); 

       inputText = new StringBuilder(); 
       while (sc.hasNext()) 
       { 
        inputText.append(sc.nextLine() + "\n"); 
       } 

      } catch (FileNotFoundException e1) { 
       e1.printStackTrace(); 
      } 

      //Set the contents of the current text area to that of the opened file 
      textArea.setText(inputText.toString()); 
     } 
    } 

} 

} 

ответ

0

Это не может быть решением для первопричину, но там могут быть некоторые несоответствия в вашем коде, который вызывает проблемы краски на TestAreas, поэтому я хотел бы предложить вам зарегистрировать TabChageListener и затем перекрасить ScrollPane для этой конкретной вкладки, это должно работать:

tabbedPanel.addChangeListener(new ChangeListener() { 
    public void stateChanged(ChangeEvent e) { 
    int selectedIndex = tabbedPane.getSelectedIndex(); 
    // get the ScrollPane for this selectedIndex and then repaint it. 

    } 
}); 
+0

Я пробовал это, но он не работал, к сожалению. Такая же проблема сохраняется. –

3

1) удалить строки кода из FileIO связанных try - catch Блоку

textArea = createTextArea(f.getName()); 
tabbedPanel.add(new JScrollPane(textArea), textArea.getName()); 
//The newly added tab is set as the active tab 
tabbedPanel.setSelectedIndex(tabbedPanel.getTabCount()-1); 
textArea.requestFocus(); 

подготовить тех, Object до того не после Input/OutputStreams

2) close() все Objects из Input/OutputStreams, в finally блоке (try - catch - finally)

3) JTextComponets реализует read() и write(), принимая все разделители, то нет оснований программно позвонить для "\ п"

4) использовать SwingWorker код для FileIO

+0

Я пробовал многое из того, что вы предложили здесь (я не знаю, как использовать SwingWorker), но все равно не повезло. –

+0

@Peter: Пожалуйста, ознакомьтесь с SwingWorker в учебниках. Я боюсь, что проблема может быть проблемой параллелизма. –

+0

Хорошо, я сделаю это. благодаря –

0

Я боролся с этой проблемой в течение последних двух часов.

На самом деле, неважно, сколько вы создаете, все они полагаются на то же самое SyntaxDocument, таким образом тот же текст. Вот как это кодируется в JEditTextArea.

В конструкторе public JEditTextArea(TextAreaDefaults defaults) вам нужно найти строку:

setDocument(defaults.document);

и заменить его:

setDocument (новый SyntaxDocument());

и он будет создавать новый Document каждый раз, когда вы делаете новый JEditTextArea.