2015-07-04 3 views
0

У меня возникла ошибка при попытке добавить компонент в JFrame.Почему JFrame не добавляет компонент правильно

Это первый класс:

import java.awt.FlowLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.*; 
public class FrameG extends JFrame 
{ 

private static final String MOVE_UP = "move up"; 
public static int frameID = 1; 
private static JFrame window = new JFrame(); 
private static openWin frame = new frame01(); 
public static void main(String[] args) { 
    window.setSize(1500,900); 
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    window.setVisible(true); 
    window.setResizable(true); 
    frame.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), MOVE_UP); 
    frame.getActionMap().put(MOVE_UP, new movement()); 
    mainloop(); 
} 
private static void mainloop() 
{ 
    window.removeAll(); 
    switch(frameID) 
    { 
     case 1: 
      frame = new frame01(); 
      frame.setLayout(new FlowLayout()); 
      System.out.println(frame); 
      window.add(frame); 
      break; 
     default: 
      break; 
    } 
    try { 
     Thread.sleep(1000); 
    } catch (InterruptedException ex) { 
     Logger.getLogger(FrameG.class.getName()).log(Level.SEVERE, null, ex); 
    } 
    mainloop(); 
} 
} 
class movement extends AbstractAction 
{ 
@Override 
public void actionPerformed(ActionEvent e) { 
    System.out.println("hi"); 
} 
} 

и второй класс (он расширяет класс с абстрактным методом краски, которая простирается JComponent):

import java.awt.Graphics; 
import java.awt.*; 
import javax.swing.JComponent; 
import java.awt.geom.*; 
public class frame01 extends openWin{ 
@Override 
public void paint(Graphics g) { 
    Graphics2D pic = (Graphics2D) g; 
    pic.setBackground(Color.BLACK); 
} 
} 

Ошибка может быть недействительной части , но я не уверен, что это такое:

frameg.frame01[,0,0,0x0,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=0,maximumSize=,minimumSize=,preferredSize=]

+0

'private static openWin frame = new frame01();' кажется подозрительным. Расширьте эту строку. –

+0

Вы метод mainLoop вызовет исключение StackOverflowException; вы не должны обновлять ui за пределами EDT; вы должны переопределять paintComponent, а не рисовать и называть super.paintComponent, прежде чем делать какую-либо обычную картину; основанный на вашем коде, я не уверен, как вы знаете какую-либо разницу между одним циклом mainLoop и другим; также вы frame01 на самом деле ничего не рисуете, поэтому он, вероятно, будет выглядеть так же, как и содержимое по умолчанию в кадре в любом случае – MadProgrammer

ответ

2

У вашего кода много проблем. Строка private static openWin frame = new frame01(); кажется подозрительной, как я сказал в своем комментарии. Но это не самое худшее:

ЭТО:

private static void mainloop() 
{ 
    window.removeAll(); 
    switch(frameID) 
    { 
     case 1: 
      frame = new frame01(); 
      frame.setLayout(new FlowLayout()); 
      System.out.println(frame); 
      window.add(frame); 
      break; 
     default: 
      break; 
    } 
    try { 
     Thread.sleep(1000); 
    } catch (InterruptedException ex) { 
     Logger.getLogger(FrameG.class.getName()).log(Level.SEVERE, null, ex); 
    } 
    mainloop(); 
} 

Является BAD! И это, вероятно, ломается, так как вы постоянно создаете new frame01() и добавляете его в свой window.

также НЕ переопределить paint, но paintComponent. Еще одна вещь, которую я не получаю, - это то, что переопределить ее в отдельном class, а не в openWin.

Другое дело, НЕ СЧИТАЙТЕ ОСНОВНУЮ РЕЗЬБОУ, если вы действительно должны запустить свой собственный и поставить ИТ для сна.

Что является целью настоящего кода? Я пытаюсь понять это, поэтому я могу помочь вам перепроектировать его.

PS: не совсем ответ, немного больше, чем комментарий.

+0

, как и для частного статического openWin frame = new frame01(); это используется, так как frame01 может содержать несколько классов, но не в одно и то же время. Я попробовал paintcomponent, но он имел тот же эффект. Кроме того, openWin является абстрактным. Я не беспокоюсь об этом, но когда я пытаюсь добавить его, он просто ничего не делает, и я думаю, что причиной является то, что недействительная вещь –

+0

@pi_squared Как я уже сказал, линия не самая худшая. Кажется, что весь дизайн вашей (предположительно) игры слаб. Почему вы рекурсивно перебираете 'mainLoop()'? –

+0

Я собираюсь добавить способ взаимодействия с компонентом позже. это просто проблема, что я не могу получить window.add (frame); working –

3

Вы код показывает явное непонимание того, как свинг работает

Это ...

private static void mainloop() 
{ 
    window.removeAll(); 
    switch(frameID) 
    { 
     case 1: 
      frame = new frame01(); 
      frame.setLayout(new FlowLayout()); 
      System.out.println(frame); 
      window.add(frame); 
      break; 
     default: 
      break; 
    } 
    try { 
     Thread.sleep(1000); 
    } catch (InterruptedException ex) { 
     Logger.getLogger(FrameG.class.getName()).log(Level.SEVERE, null, ex); 
    } 
    mainloop(); 
} 

плохая идея по двум причинам, первая в том, что он будет в конечном итоге генерировать StackOverflowException, во-вторых, он нарушает правила нитей Swing.

Обычно while-loop в целом будет лучше, но, как вы имеете дело с компонентами на основе Swing, вы должны рассмотреть возможность использования либо Свинг Timer или SwingWorker, в зависимости от того, что вы надеетесь достичь.

Постоянно добавлять и удалять компоненты также кажутся странной идеей, но нет никакого смысла в вопросе, чтобы знать, что именно вы надеетесь достичь. Сказав, что, как правило, если вы хотите переключиться между видами, то CardLayout обычно считается предпочтительным решением

Это ...

public class frame01 extends openWin{ 
    @Override 
    public void paint(Graphics g) { 
     Graphics2D pic = (Graphics2D) g; 
     pic.setBackground(Color.BLACK); 
    } 
} 

не просто делает ничего, другой затем разорвать цепь краски, которая может привести ни конца странных артефактов краски не будут созданы. Все, что вы делает код, если временно изменяет цвет фона Graphics контекста, но так как вы ничего не рисовать с ним, это эффективно бессмысленными

Как правило, рекомендуется, чтобы переопределить paintComponent метод компонентов Swing, (и позвоните по номеру super.paintComponent, прежде чем выполнять какую-либо обычную роспись).

я настоятельно рекомендую вам взглянуть на:

1

Никогда не используйте нить, и она запускается и останавливается как таймер. Вместо этого используйте javax.swing.Timer. Также вы создали рекурсивную функцию для реализации бесконечного цикла, который очень проложен и подвержен ошибкам. У Swing есть собственный поток, и когда вы смешиваете его с другими потоками бессознательно, он превращает ваш код в монстра, которого мы все боимся.