2014-11-12 2 views
0

У меня такая странная проблема с Swing. Я рисую несколько точек и линий между ними, непосредственно на JPanel. Я просто звоню:Swing auto repaints JPanel после нажатия кнопки

g.drawLine(pointAX, pointAY, pointBX, pointBY); 

где G- Graphics объект взят из panel.getGraphics()

И это работает хорошо, дает мне хороший выход. Но я стараюсь, чтобы переместить его, и я использую ActionListener на моей кнопки, которая делает:

panel.revalidate(); 
    panel.repaint(); 
    drawPanel(); 
    moveVector(moveX, moveY); 

    drawPoints(); 
    drawConnections(connections); 

Другие методы: drawPanel просто рисует несколько линий, так что легче увидеть:

private void drawPanel(){ 
    Graphics g = panel.getGraphics(); 
    zeroX = panel.getWidth()/2; 
    zeroY = panel.getHeight()/2; 

    g.setColor(Color.GRAY); 

    for(int i = zeroX + 10; i < panel.getWidth(); i += 10){ 
     g.drawLine(i, 0, i, panel.getHeight()); 
    } 

    for(int i = zeroX + 10; i > 0; i -= 10){ 
     g.drawLine(i, 0, i, panel.getHeight()); 
    } 

    for(int j = zeroY - 10; j < panel.getHeight(); j += 10){ 
     g.drawLine(0, j, panel.getWidth(), j); 
    } 

    for(int j = zeroY - 10; j > 0; j -= 10){ 
     g.drawLine(0, j, panel.getWidth(), j); 
    } 

    g.setColor(Color.BLACK); 
    g.drawLine(zeroX, 0, zeroX, panel.getHeight()); 
    g.drawLine(0, zeroY, panel.getWidth(), zeroY); 

    panel.paintComponents(g); 
} 

drawPoints выглядит следующим образом

private void drawPoints() { 
    for(int i = 0; i < points.size(); i++){ 
     int x = Integer.parseInt(points.get(i)[1]); 
     int y = Integer.parseInt(points.get(i)[2]); 
     drawPoint(x, y); 
    } 
} 

private void drawPoint(int x, int y) { 
    Graphics g = panel.getGraphics(); 

    for (int i = -1; i < 2; i++) { 
     g.drawLine(zeroX + x + i, zeroY + y - 1, zeroX + x + i, zeroY + y); 
    } 

    panel.paintComponents(g); 
} 

    g.setColor(Color.BLACK); 
    g.drawLine(zeroX, 0, zeroX, panel.getHeight()); 
    g.drawLine(0, zeroY, panel.getWidth(), zeroY); 

    panel.paintComponents(g); 
} 

и drawConnections:

private void drawConnections(ArrayList<String[]> lines) { 
    for (String[] arr : lines) { 
     String x = arr[1]; 
     String y = arr[2]; 

     drawConnection(x, y); 
    } 
} 

private void drawConnection(String pointA, String pointB) { 
    int pointAX = 0, pointAY = 0, pointBX = 0, pointBY = 0; 
    Graphics g = panel.getGraphics(); 

    for (String[] arr : points) { 
     if (arr[0].equals(pointA)) { 
      pointAX = Integer.parseInt(arr[1]); 
      pointAY = Integer.parseInt(arr[2]); 
     } else if (arr[0].equals(pointB)) { 
      pointBX = Integer.parseInt(arr[1]); 
      pointBY = Integer.parseInt(arr[2]); 
     } 
    } 

    g.drawLine(zeroX + pointAX, zeroY + pointAY, zeroX + pointBX, zeroY + pointBY); 
    panel.paintComponents(g); 
} 

Что я не понимаю, так это то, что все выглядит нормально. Я отлаживал и выглядел нормально, и в конце вызова слушателя, когда все окрашивается (хотя оно красуется над старым, а не очищает его), оно внезапно очищает все, и ничего не видно вообще.

+0

Вы не смогли высказать свое мнение? (Может быть на любом другом сайте, например [pastebin] (http://pastebin.com/) – afzalex

+0

http://pastebin.com/pLrKd7AB Вот код Стоит упомянуть, что я использую IntelliJ, и он использует какой-то создатель, чтобы помочь сделать GUI. Он скрывает часть реализации – user3212350

+0

'getGraphics' - это не то, как делается живопись, посмотрите на [Живопись в AWT и Swing] (http://www.oracle.com/technetwork/java/painting-140037.html) и [Выполнение пользовательской живописи] (http://docs.oracle.com/javase/tutorial/uiswing/painting/) для более подробной информации ... – MadProgrammer

ответ

0

panel.repaint не сразу перекрасить панель, но он говорит Качели, что эта панель должна быть перекрашены в ближайшем будущем (см API документы:. https://docs.oracle.com/javase/7/docs/api/javax/swing/JComponent.html#repaint(long,%20int,%20int,%20int,%20int) Так что ваш заказ картина будет стерта, как только панель перерисовывает себя

. Создайте пользовательский компонент, наследуя от JPanel и переписывая метод paintComponent с вашим пользовательским кодом рисования. Затем, когда панель должна быть перекрашена, вызывается код, и не только пользователь нажимал кнопку.

1

Вам необходимо выполните весь чертеж в paintComponent(Graphics) в вашем классе JPanel (или методах, которые являются cal привело к этому). Вызов getGraphics на экземпляр панели и использование объекта Graphics не всегда гарантированно работают. Также странно, что вы вызываете panel.repaint() и сразу после этого пытаетесь сделать дополнительный чертеж с помощью графического объекта с панели, что дополнительный чертеж должен быть сделан только в paintComponent(Graphics).

Использование paintComponent(Graphics) гарантирует, что ваша картина будет выполнена в нужное время и что графическая панель панели будет очищена (если вы вызовете метод супер по крайней мере).

Смежные вопросы