2016-12-13 1 views
0

나는 변화하는 색상과 움직이는 도형으로 움직이는 스크린 세이버를 만들려고 노력하고 있습니다. 또한 일종의 트레일 효과를 원합니다 (예를 들어, 설정하지 않으면 각 픽셀의 가장 최근 색이 계속 그려지는 것과 같이). 배경색). 전에 한 번이 효과를 얻었지만 어떻게했는지 모르겠습니다. 현재 결과는 움직이는 사각형으로 회색 배경 전체에 색상이 바뀝니다. ScreenSaver.java업데이트되지 않는 JPanel 배경을 만드는 방법은 무엇입니까?

import java.awt.Color; 
import java.awt.Component; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JPanel; 
import javax.swing.Timer; 

public class ScreenSaver extends JPanel 
{ 
    public static Component sc; 
    public int delay = 1000/2; 
    public int state = 0; 
    public int re = 255; 
    public int gr = 0; 
    public int bl = 0; 
    public int d = 1; 
    ScreenSaver() 
    { 
     ActionListener counter = new ActionListener() 
     { 
      public void actionPerformed(ActionEvent event) 
      { 
       updateUI(); 
       repaint(); 
      } 
     }; 
     new Timer(delay, counter).start(); 
     System.out.println("this is the secret screensaver that appears after 30 seconds of no mouse activity");//i have this line here so it doesn't print every time the screen updates 
    } 

    public void paintComponent(Graphics g) 
    { 
     super.paintComponent(g); 
     this.setBackground(null); 
     if (state == 0) 
     { 
      gr++; 
      if(gr == 255) 
       state = 1; 
     } 
     if (state == 1) 
     { 
      re--; 
      if(re == 0) 
       state = 2; 
     } 
     if (state == 2) 
     { 
      bl++; 
      if(bl == 255) 
       state = 3; 
     } 
     if (state == 3) 
     { 
      gr--; 
      if(gr == 0) 
       state = 4; 
     } 
     if (state == 4) 
     { 
      re++; 
      if(re == 255) 
       state = 5; 
     } 
     if (state == 5) 
     { 
      bl--; 
      if(bl == 0) 
       state = 0; 
     } 
     g.setColor(new Color(re, gr, bl)); 
     d++; 
     g.fillRect(d, 50, 50, 50); 
    } 
    public static void main(String[] args) 
    { 
     //ScreenSaver sc = new ScreenSaver(); 
    } 
} 

Main.java : (ScreenSaver.java이 파일을 통해 객체라고한다)

import java.awt.Color; 
import java.awt.Graphics; 
//import java.util.Random; 

//import javax.swing.AbstractAction; 
//import javax.swing.Action; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import java.awt.event.MouseEvent; 
import java.awt.event.MouseMotionListener; 

import javax.swing.Timer; 

public class FinalProject extends JPanel implements MouseMotionListener 
{ 
    public int delay = 1000/2; 
    public boolean screenActive = true; 
    public int why = 1; 
    FinalProject() 
    { 
     ActionListener counter = new ActionListener() 
     { 
      public void actionPerformed(ActionEvent event) 
      { 
       updateUI(); 
       repaint(); 
      } 
     }; 
     new Timer(delay, counter).start(); 
    } 
    static JFrame jf = new JFrame(); 

    public void paintComponent(Graphics g) 
    { 
     super.paintComponent(g); 
     this.setBackground(Color.BLACK); 
     if (screenActive) 
     { 
      why++; 
     } 
     if (why == 6) 
     { 
      why = 0; 
      System.out.println("inactivity detected"); 
      screenActive = false; 
      ScreenSaver sc = new ScreenSaver(); 
      jf.add(sc); 
     } 
    } 

    public static void main(String[] args) throws InterruptedException 
    { 
     System.out.println("Welcome to Computer Simulator 0.1"); 
     System.out.println("this is the main screen"); 
     FinalProject e = new FinalProject(); 
     //ScreenSaver sc = new ScreenSaver(); 
     jf.setTitle("game"); 
     jf.setSize(500,500); 
     //jf.setUndecorated(true); 
     //jf.setBackground(new Color(1.0f,1.0f,1.0f,0.5f)); 
     jf.setVisible(true); 
     jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     //jf.add(new ScreenSaver()); 
     jf.add(e); 
    } 

    @Override 
    public void mouseDragged(MouseEvent arg0) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void mouseMoved(MouseEvent MOUSE_MOVED) 
    { 

    } 
} 
+0

빈 메소드 인'repaint'를 오버라이드하고 직접'update'를 호출하면 원하는 결과를 얻으실 수 있습니까? –

+0

@DanArmstrong, update()를 직접 호출하지 마십시오. 스윙에는 잘 정의 된 페인팅 계층 구조가 있으며이를 재정의해서는 안됩니다. 한 가지 방법으로이 접근법은 이중 버퍼링을 제거합니다. – camickr

+0

정확하게 제안한 이유. 그들은 비표준 효과를 얻기 위해 스윙을 해킹하고 싶어하는 것 같습니다. 그러나 해킹/악용을 제쳐두고, 아래의 대답은 BufferedImages를 사용하거나 페인트에 항목을 다시 그리는 방법입니다. –

답변

2

가에 updateUI를 호출하지 마십시오(). 구성 요소가 자체적으로 다시 칠하게하려면 repaint() 만 있으면됩니다.

BufferedImage에 드로잉을 한 다음 BufferedImage를 사용하여 JLabel에 추가하는 ImageIcon을 만드는 것도 한 가지 방법입니다.

다른 방법으로는 페인트 할 개체의 목록을 유지 한 다음 구성 요소를 다시 칠 때마다 목록을 반복하는 것입니다.

작업 예제와 두 가지 방법 중 어느 것을 사용할 지에 대한 분석은 Custom Painting Approches을 확인하십시오.

관련 문제