2014-10-13 4 views
-1

Я использую JFrame Java для отображения изображения .jpeg. Мне нужно запустить горизонтальный эффект скольжения на изображение при выборе флажка. Таким образом, в основном, когда установлен флажок, изображение начнет скользить слева направо, сделав несколько секунд, и когда закончите, начните снова навсегда, пока флажок не будет снят. Как я могу добавить эту функцию?Добавить эффект видимости для изображений в Java JFrame

EDIT: На самом деле я не имею в виду, что сама картинка движется; Я имею в виду, что изображение стабильно и статично, но изображение начнет становиться видимым с горизонтальным скользящим эффектом, слева направо и перезапуском. Надеюсь, это достаточно ясно.

Предположим, вот мой код, чтобы показать изображения и флажков (получил от Java учебник):

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

/* 
* CheckBoxDemo.java requires 16 image files in the images/geek 
* directory: 
* geek-----.gif, geek-c---.gif, geek--g--.gif, geek---h-.gif, geek----t.gif, 
* geek-cg--.gif, ..., geek-cght.gif. 
*/ 
public class CheckBoxDemo extends JPanel 
          implements ItemListener { 
    JCheckBox chinButton; 
    JCheckBox glassesButton; 
    JCheckBox hairButton; 
    JCheckBox teethButton; 

    /* 
    * Four accessory choices provide for 16 different 
    * combinations. The image for each combination is 
    * contained in a separate image file whose name indicates 
    * the accessories. The filenames are "geek-XXXX.gif" 
    * where XXXX can be one of the following 16 choices. 
    * The "choices" StringBuffer contains the string that 
    * indicates the current selection and is used to generate 
    * the file name of the image to display. 

     ----    //zero accessories 

     c---    //one accessory 
     -g-- 
     --h- 
     ---t 

     cg--    //two accessories 
     c-h- 
     c--t 
     -gh- 
     -g-t 
     --ht 

     -ght    //three accessories 
     c-ht 
     cg-t 
     cgh- 

     cght    //all accessories 
    */ 

    StringBuffer choices; 
    JLabel pictureLabel; 

    public CheckBoxDemo() { 
     super(new BorderLayout()); 

     //Create the check boxes. 
     chinButton = new JCheckBox("Chin"); 
     chinButton.setMnemonic(KeyEvent.VK_C); 
     chinButton.setSelected(true); 

     glassesButton = new JCheckBox("Glasses"); 
     glassesButton.setMnemonic(KeyEvent.VK_G); 
     glassesButton.setSelected(true); 

     hairButton = new JCheckBox("Hair"); 
     hairButton.setMnemonic(KeyEvent.VK_H); 
     hairButton.setSelected(true); 

     teethButton = new JCheckBox("Teeth"); 
     teethButton.setMnemonic(KeyEvent.VK_T); 
     teethButton.setSelected(true); 

     //Register a listener for the check boxes. 
     chinButton.addItemListener(this); 
     glassesButton.addItemListener(this); 
     hairButton.addItemListener(this); 
     teethButton.addItemListener(this); 

     //Indicates what's on the geek. 
     choices = new StringBuffer("cght"); 

     //Set up the picture label 
     pictureLabel = new JLabel(); 
     pictureLabel.setFont(pictureLabel.getFont().deriveFont(Font.ITALIC)); 
     updatePicture(); 

     //Put the check boxes in a column in a panel 
     JPanel checkPanel = new JPanel(new GridLayout(0, 1)); 
     checkPanel.add(chinButton); 
     checkPanel.add(glassesButton); 
     checkPanel.add(hairButton); 
     checkPanel.add(teethButton); 

     add(checkPanel, BorderLayout.LINE_START); 
     add(pictureLabel, BorderLayout.CENTER); 
     setBorder(BorderFactory.createEmptyBorder(20,20,20,20)); 
    } 

    /** Listens to the check boxes. */ 
    public void itemStateChanged(ItemEvent e) { 
     int index = 0; 
     char c = '-'; 
     Object source = e.getItemSelectable(); 

     if (source == chinButton) { 
      index = 0; 
      c = 'c'; 
     } else if (source == glassesButton) { 
      index = 1; 
      c = 'g'; 
     } else if (source == hairButton) { 
      index = 2; 
      c = 'h'; 
     } else if (source == teethButton) { 
      index = 3; 
      c = 't'; 
     } 

     //Now that we know which button was pushed, find out 
     //whether it was selected or deselected. 
     if (e.getStateChange() == ItemEvent.DESELECTED) { 
      c = '-'; 
     } 

     //Apply the change to the string. 
     choices.setCharAt(index, c); 

     updatePicture(); 
    } 

    protected void updatePicture() { 
     //Get the icon corresponding to the image. 
     ImageIcon icon = createImageIcon(
            "images/geek/geek-" 
            + choices.toString() 
            + ".gif"); 
     pictureLabel.setIcon(icon); 
     pictureLabel.setToolTipText(choices.toString()); 
     if (icon == null) { 
      pictureLabel.setText("Missing Image"); 
     } else { 
      pictureLabel.setText(null); 
     } 
    } 

    /** Returns an ImageIcon, or null if the path was invalid. */ 
    protected static ImageIcon createImageIcon(String path) { 
     java.net.URL imgURL = CheckBoxDemo.class.getResource(path); 
     if (imgURL != null) { 
      return new ImageIcon(imgURL); 
     } else { 
      System.err.println("Couldn't find file: " + path); 
      return null; 
     } 
    } 

    /** 
    * Create the GUI and show it. For thread safety, 
    * this method should be invoked from the 
    * event-dispatching thread. 
    */ 
    private static void createAndShowGUI() { 
     //Create and set up the window. 
     JFrame frame = new JFrame("CheckBoxDemo"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     //Create and set up the content pane. 
     JComponent newContentPane = new CheckBoxDemo(); 
     newContentPane.setOpaque(true); //content panes must be opaque 
     frame.setContentPane(newContentPane); 

     //Display the window. 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     //Schedule a job for the event-dispatching thread: 
     //creating and showing this application's GUI. 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowGUI(); 
      } 
     }); 
    } 
} 
+0

* «может кто-то помочь мне с этим?» * в частности, что вы имеете в виду под этим? Например, здесь он читается как «Может ли кто-то закончить это для меня?». На что ответ будет «VTC и пониженное голосование». –

ответ

4

Самым простым решением было бы свернуть свой собственный, используя что-то вроде javax.swing.Timer, например ...

Fly baby, fly

import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class SlidingAnimation { 

    public static void main(String[] args) { 
     new SlidingAnimation(); 
    } 

    public SlidingAnimation() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private BufferedImage img; 
     private int x = 0; 

     private Timer timer; 
     private long startTime = -1; 
     private int playTime = 4000; 

     public TestPane() { 
      try { 
       img = ImageIO.read(new File("...")); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 
      timer = new Timer(40, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        float progress = 0f; 
        if (startTime == -1) { 
         startTime = System.currentTimeMillis(); 
        } else { 
         long currentTime = System.currentTimeMillis(); 
         long diff = currentTime - startTime; 

         if (diff >= playTime) { 
          diff = 0; 
          startTime = -1; 
         } 
         progress = diff/(float)playTime; 
        } 

        x = (int)((getWidth() - img.getWidth()) * progress); 
        repaint(); 
       } 
      }); 
      timer.start(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return img == null ? new Dimension(200, 200) : new Dimension(img.getWidth() * 2, img.getHeight()); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      if (img != null) { 
       Graphics2D g2d = (Graphics2D) g.create(); 
       int y = (getHeight() - img.getHeight())/2; 
       g2d.drawImage(img, x, y, this); 
       g2d.dispose(); 
      } 
     } 

    } 

} 

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

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

  • The Timing Framework. Обеспечивает хороший доступ к ядру, чтобы делать необычные вещи, но также имеет возможность изменять свойства объектов с течением времени.
  • Trident. Предоставляет возможность изменять свойства объектов с течением времени
  • Universal Tween Engine, который я не использовал, но выглядит действительно хорошо.

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

Обновлено

Итак, если я понимаю, ваши комментарии, вы хотите сделать эффект перекрестного затухания. Теперь есть несколько способов сделать это, вы можете использовать BufferedImage#subImage, чтобы получить «обрезанную» версию исходного изображения и показать это, но это, IMHO, не производит такого приятного эффекта ...

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

enter image description here

import java.awt.AlphaComposite; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.LinearGradientPaint; 
import java.awt.Rectangle; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.geom.Point2D; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class SlidingAnimation { 

    public static void main(String[] args) { 
     new SlidingAnimation(); 
    } 

    public SlidingAnimation() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private BufferedImage img; 

     private Timer timer; 
     private long startTime = -1; 
     private int playTime = 4000; 

     private float progress; 

     public TestPane() { 
      try { 
       img = ImageIO.read(new File("...")); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 
      timer = new Timer(40, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        if (startTime == -1) { 
         startTime = System.currentTimeMillis(); 
        } else { 
         long currentTime = System.currentTimeMillis(); 
         long diff = currentTime - startTime; 

         if (diff >= playTime) { 
          diff = 0; 
          startTime = -1; 
         } 
         progress = diff/(float) playTime; 
        } 

        repaint(); 
       } 
      }); 
      timer.start(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return img == null ? new Dimension(200, 200) : new Dimension(img.getWidth(), img.getHeight()); 
     } 

     protected BufferedImage generateImage() { 

      BufferedImage buffer = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB); 
      Graphics2D g2d = buffer.createGraphics(); 
      g2d.setBackground(new Color(0, 0, 0, 0)); 
      g2d.clearRect(0, 0, buffer.getWidth(), buffer.getHeight()); 
      g2d.drawImage(img, 0, 0, this); 

      float startAt = progress - 0.05f; 
      float endAt = progress + 0.05f; 

      if (endAt <= 0.1f) { 
       startAt = 0; 
       endAt = Math.max(0.1f, progress); 
      } else if (endAt >= 1f) { 
       endAt = 1f; 
       startAt = progress; 
      } 

      LinearGradientPaint lgp = new LinearGradientPaint(
        new Point2D.Float(0, 0), 
        new Point2D.Float(img.getWidth(), 0), 
        new float[]{startAt, endAt}, 
        new Color[]{new Color(0, 0, 0, 0), Color.RED}); 

      g2d.setPaint(lgp); 

      g2d.setComposite(AlphaComposite.DstOut.derive(1f)); 
      g2d.fill(new Rectangle(0, 0, img.getWidth(), img.getHeight())); 
      g2d.dispose(); 

      return buffer; 

     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      if (img != null) { 
       Graphics2D g2d = (Graphics2D) g.create(); 
       int y = (getHeight() - img.getHeight())/2; 
       int x = (getWidth() - img.getWidth())/2; 
       g2d.drawImage(generateImage(), x, y, this); 

       g2d.dispose(); 
      } 
     } 

    } 

} 
+0

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

+0

Вы хотите, чтобы вы поменяли изображение слева направо? – MadProgrammer

+0

Да! Спасибо за вашу фотографию. Однако на вашем снимке правый конец изображения постепенно исчезает, а не резкий, в то время как я думал о резкой скользящей кромке. –

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