2016-05-24 5 views
0

У меня есть неэффективный код прямоугольной волны. У меня есть 2 кнопки, 1 таблица и что-то вроде системы координат, в которой появляется квадрат. Я хочу, чтобы волна прокручивалась/двигалась в реальном времени, пока она не попала в конец системы координат, вместо того, чтобы просто появляться, выбрав обе кнопки. Кроме того, если у кого-то есть лучший способ рисовать квадратную волну, пожалуйста, скажите мне.Создание прямоугольной волны в JFrame

public void paint(Graphics g) { 
    super.paint(g); 
    Graphics2D g2d = (Graphics2D) g; 
    g2d.drawLine(20, 300, 20, 450); 
    g2d.drawLine(20, 350, 400, 350); 
    g2d.drawLine(20, 400, 400, 400); 
    g2d.drawLine(20, 450, 400, 450); 

    if (this.jButtonSTART.isSelected() & this.jButtonAND.isSelected()) { 
      this.draw(g2d); 
     } 
} 

public void draw(Graphics2D g2d) { 
    boolean up = true; 
    while (x <= 380) { 
     g2d.setColor(Color.blue); 
     if (x > 0 && x % 95 == 0) { 
      up = !up; 
      g2d.drawLine(20 + x, up ? 315 : 350 + y, 20 + x, up ? 350 : 315 + y); 
     } else { 
      if (up) { 
       g2d.drawLine(20 + x, 315 + y, 21 + x, y + 315); 
      } else { 
       g2d.drawLine(20 + x, 350 + y, 21 + x, y + 350); 
      } 
     } 
     x++; 
    } 
    x = 0; 
} 

ответ

0

Простой способ сделать свой меандр и переместить его:

  1. Создать BufferedImage, который больше, чем ваш GUI. Он должен иметь длину, которая соответствует периоду вашей прямоугольной волны и должна быть как минимум в два раза длиннее компонента GUI, который он отображает.
  2. Ничья в методе paintComponent переопределяет JPanel, а не метод рисования.
  3. Сначала вызовите метод paint paintComponent в пределах вашего переопределения.
  4. Вы рисуете изображение с помощью g.drawImage(myImage, imageX, imageY, this), где imageX и imageY являются частными полями экземпляра класса рисования, расширяемого JPanel.
  5. В качающемся таймере, вперед imageX с каждым тиком таймера, который каждый раз вызывается его ActionPerformed метод ActionListener).
  6. Затем вызовите repaint() на чертеже JPanel в рамках одного и того же метода actionPerformed.
  7. Выполнено.

например, обратите внимание, что этот код не выполняет точно то, что вы пытаетесь сделать, но показывает пример анимации Swing с использованием таймера Swing и paintComponent.

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.GradientPaint; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.image.BufferedImage; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class MoveWave extends JPanel { 
    private static final int PREF_W = 400; 
    private static final int PREF_H = 200; 
    private static final int TIMER_DELAY = 40; 
    public static final int DELTA_X = 2; 
    public static final int STARTING_MY_IMAGE_X = -PREF_W; 
    private static final Color COLOR_1 = Color.RED; 
    private static final Color COLOR_2 = Color.BLUE; 
    private static final Color BG = Color.BLACK; 
    private static final int CIRCLE_COUNT = 10; 
    private BufferedImage myImage = null; 
    private int myImageX = STARTING_MY_IMAGE_X; 
    private int myImageY = 0; 

    public MoveWave() { 
     setBackground(BG); 
     myImage = new BufferedImage(2 * PREF_W, PREF_H, BufferedImage.TYPE_INT_ARGB); 
     Graphics2D g2 = myImage.createGraphics(); 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g2.setPaint(new GradientPaint(0, 0, COLOR_1, 20, 20, COLOR_2, true)); 
     for (int i = 0; i < CIRCLE_COUNT; i++) { 
      int x = (i * 2 * PREF_W)/CIRCLE_COUNT; 
      int y = PREF_H/4; 
      int width = (2 * PREF_W)/CIRCLE_COUNT; 
      int height = PREF_H/2; 
      g2.fillOval(x, y, width, height); 
     } 
     g2.dispose(); 
     new Timer(TIMER_DELAY, new TimerListener()).start(); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     if (myImage != null) { 
      g.drawImage(myImage, myImageX, myImageY, this); 
     } 
    } 
    @Override 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet()) { 
      return super.getPreferredSize(); 
     } 
     return new Dimension(PREF_W, PREF_H); 
    } 

    private class TimerListener implements ActionListener { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      myImageX += DELTA_X; 
      if (myImageX >= 0) { 
       myImageX = STARTING_MY_IMAGE_X;       
      } 
      repaint(); 
     } 
    } 

    private static void createAndShowGui() { 
     JFrame frame = new JFrame("MoveWave"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(new MoveWave()); 
     frame.setResizable(false); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 
} 
+1

Действия вашего таймераПередформированный метод должен сбрасывать значение imageX всякий раз, когда он достигает полной длины волны. и вы также должны добавить компонент ComponentListener, метод componentResized() повторно создает изображение для нового размера компонента. – FredK

+0

@FredK: true, или для моей примерной программы (см. Выше), я просто фиксирую размер графического интерфейса. –

+0

@Hovercraft Full of Eels Большое спасибо за помощь! Я на самом деле просто новичок, поэтому мне сложно понять ваши шаги. Вы потеряли меня после второго шага. Не могли бы вы быть более сложными? Я предполагаю, что вы хотели, чтобы я создал метод paintComponent, потому что я didn – Nest