2012-11-08 62 views
2

我即将开始一个Java项目,我本质上是一个虚拟的iTunes克隆。我将使用Swing来制作GUI,但我想知道以不同于颜色/字体/边框的iTunes类似于iTunes的最佳方式。我已经研究过使用CSS和Java Swing,但是我发现的任何资源都过时了。有没有新的方法来解决这个问题?或者我应该寻找除CSS之外的东西?CSS3风格的Java?

这是我期待通过摆动来实现(基础至少)设计: enter image description here

+2

缺少屏幕截图,只是基于您的描述,我建议寻找可插拔的外观和感觉。 –

+0

@AndrewThompson我添加了我期待实现的设计屏幕截图。 – Jakemmarsh

+0

有一大堆用于Java的LaF,甚至内置的也是可换肤的。我建议你选择一个你喜欢的,或者如果你真的需要自定义的外观,写一个皮肤。 – millimoose

回答

6

有与Swing没有CSS样式。但是,如果您使用JavaFx2,它是Swing的后继者,那么您可以使用CSS样式。

如果你是不是已经很熟悉的Swing,我建议你考虑的JavaFX。 Java的最新1.7版本内置JavaFX 2.2。它具有CSS支持和一个Media Player

它当然也可以在Swing中完成。你可以使用许多不同的方法,但为了给你一个出发点,这里是我将如何创建按钮。这种方法需要Java 7,但是如果使用JXLayer,也可以在以前版本的Java中运行它。这些按钮是2D涂料和我可以访问的一些图标的组合。只需使用图标进行更改即可。圆圈的大小将根据您使用的图像调整大小。

当你点击按钮,在这里你会发出蜂鸣声,以及相应的文本打印到控制台。一般来说,JLayer对于Swing应用程序的样式非常有用。

Example of Media PLayer

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.geom.Ellipse2D; 
import java.awt.geom.Rectangle2D; 
import java.net.URL; 
import java.util.logging.Logger; 

import javax.swing.*; 
import javax.swing.plaf.LayerUI; 

/** 
*/ 
public class MediaPlayer { 

    public static void main(String[] args) { 

     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame frame = new JFrame("Media Clone"); 
       MediaController mediaController = new MediaController(); 
       frame.getContentPane().add(new MediaView(mediaController)); 
       frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
       frame.setMinimumSize(new Dimension(800, 450)); 
       frame.setLocationRelativeTo(null); // Center 
       frame.pack(); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    static class MediaView extends JPanel { 

     private MediaList mediaList; 
     private ButtonView buttonView; 
     private MediaController controller; 

     MediaView(MediaController controller) { 
      this.controller = controller; 
      createComponents(); 
      makeLayout(); 
     } 

     public void createComponents() { 
      mediaList = new MediaList(); 
      buttonView = new ButtonView(controller); 
     } 

     public void makeLayout() { 
      setLayout(new BorderLayout()); 
      add(mediaList); 
      add(new JLayer<>(buttonView, new GradientUI()), BorderLayout.NORTH); 
     } 
    } 

    static class MediaList extends JPanel { 

     private JTable mediaTable; 

     MediaList() { 
      createComponents(); 
      makeLayout(); 
     } 

     public void createComponents() { 
      String[] header = new String[]{"Song", "Artist"}; 
      String[][] model = new String[2][2]; 
      model[0][0] = "Hello"; 
      model[0][1] = "World"; 
      model[1][0] = "Goodbye"; 
      model[1][1] = "Sunshine"; 
      mediaTable = new JTable(model, header); 
     } 

     public void makeLayout() { 
      setLayout(new BorderLayout()); 
      add(new JScrollPane(mediaTable)); 
     } 
    } 

    static class GradientUI extends LayerUI<JComponent> { 

     @Override 
     public void paint(Graphics g, JComponent c) { 
      Graphics2D g2 = (Graphics2D) g.create(); 
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
      g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 
      int height = c.getHeight(); 
      int width = c.getWidth(); 
      g2.setPaint(new GradientPaint(0, 0, new Color(136, 146, 155), 0, height, new Color(101, 108, 116))); 
      Rectangle2D area = new Rectangle(0, 0, width, height); 
      g2.fill(area); 
      super.paint(g2, c); 
     } 
    } 

    enum MediaAction { 
     PLAY, NEXT, PREVIOUS 
    } 

    static class MediaController { 

     private Toolkit toolkit = Toolkit.getDefaultToolkit(); 

     public void execute(MediaAction mediaAction) { 
      toolkit.beep(); 
      System.out.println(mediaAction.name()); 
     } 
    } 

    static class ButtonView extends JPanel { 

     private static Logger log = Logger.getLogger(ButtonView.class.getName()); 

     private JButton play; 
     private JButton next; 
     private JButton previous; 
     private RoundButtonUI playUI; 
     private ActionListener playActionListener; 
     private ActionListener nextActionListener; 
     private ActionListener previousActionListener; 
     private MediaController controller; 

     ButtonView(MediaController controller) { 
      this.controller = controller; 
      createComponents(); 
      makeLayout(); 
      createHandlers(); 
      registerHandlers(); 
      initComponent(); 
     } 

     public void createComponents() { 
      play = new JButton(); 
      next = new JButton(); 
      previous = new JButton(); 
      playUI = new RoundButtonUI(); 
     } 

     public void createHandlers() { 
      playActionListener = createMediaAction(MediaAction.PLAY); 
      nextActionListener = createMediaAction(MediaAction.NEXT); 
      previousActionListener = createMediaAction(MediaAction.PREVIOUS); 
     } 

     private ActionListener createMediaAction(final MediaAction mediaAction) { 
      return new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        SwingUtilities.invokeLater(new Runnable() { 
         @Override 
         public void run() { 
          controller.execute(mediaAction); 
         } 
        }); 
       } 
      }; 
     } 

     public void registerHandlers() { 
      play.addActionListener(playActionListener); 
      next.addActionListener(nextActionListener); 
      previous.addActionListener(previousActionListener); 
     } 

     public void makeLayout() { 
      setLayout(new FlowLayout(FlowLayout.LEADING)); 
      makeButtonRound(previous, "<<", "bullet_triangle_grey_shadow.png", "bullet_triangle_grey.png"); 
      makeButtonRound(play, ">", "bullet_triangle_glass_grey128x128.png", "bullet_triangle_glass_grey128x128.png"); 
      makeButtonRound(next, ">>", "bullet_triangle_grey_shadow.png", "bullet_triangle_grey.png"); 
      add(new JLayer<>(previous, playUI)); 
      add(new JLayer<>(play, playUI)); 
      add(new JLayer<>(next, playUI)); 
     } 

     public void initComponent() { 
      setOpaque(false); 
     } 

     private void makeButtonRound(final JButton toBeRounded, String fallback, String imageNormal, String imagePressed) { 
      toBeRounded.setOpaque(false); 
      toBeRounded.setFocusPainted(false); 
      toBeRounded.setBorderPainted(false); 
      toBeRounded.setContentAreaFilled(false); 
      toBeRounded.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 5)); 
      URL normalURL = getClass().getClassLoader().getResource(imageNormal); 
      URL pressedURL = getClass().getClassLoader().getResource(imagePressed); 
      if (normalURL != null || pressedURL != null) { 
       final ImageIcon released = new ImageIcon(normalURL); 
       final ImageIcon pressed = new ImageIcon(pressedURL); 
       toBeRounded.setIcon(released); 
       toBeRounded.addMouseListener(new MouseAdapter() { 
        @Override 
        public void mousePressed(MouseEvent e) { 
         toBeRounded.setIcon(pressed); 
        } 

        @Override 
        public void mouseReleased(MouseEvent e) { 
         toBeRounded.setIcon(released); 
        } 
       }); 
      } else { 
       toBeRounded.setText(fallback); 
       log.severe("Missing resources: " + imageNormal + " and " + imagePressed); 
      } 
     } 
    } 

    /** 
    * Shifts the image so it looks pressed down. 
    * Creates a circle around the icon, that varies in size depending on the supplied icon. 
    */ 
    static class RoundButtonUI extends LayerUI<JComponent> { 

     private static final int STROKE_WIDTH = 5; 

     @Override 
     public void paint(Graphics g, JComponent c) { 
      Graphics2D g2 = (Graphics2D) g.create(); 
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
      g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 

      ButtonModel buttonModel; 
      JButton b; 

      if (((JLayer) c).getView() instanceof JButton) { 
       b = (JButton) ((JLayer) c).getView(); 
       buttonModel = b.getModel(); 
      } else { 
       super.paint(g, c); 
       return; 
      } 

      int iconHeight = b.getIcon() != null ? b.getIcon().getIconHeight() : 60; 
      int iconWidth = b.getIcon() != null ? b.getIcon().getIconWidth() : 60; 

      Shape circle = new Ellipse2D.Double(STROKE_WIDTH, STROKE_WIDTH, iconHeight, iconWidth); 

      g2.setPaint(new GradientPaint(5, 5, new Color(222, 224, 230), 30, 55, new Color(187, 189, 199))); 
      g2.fill(circle); 

      g2.setPaint(new GradientPaint(15, 0, new Color(90, 97, 105), 15, 30, new Color(132, 142, 152))); 
      g2.setStroke(new BasicStroke(5)); 
      g2.draw(circle); 

      if (buttonModel.isPressed()) { 
       g2.translate(1, 1); 
      } 

      super.paint(g2, c); 
      g2.dispose(); 
     } 
    } 
} 
+0

寻找更多的JavaFX,它可能就是我正在寻找的东西。我现在正在安装它,我将不得不做更多的研究。谢谢! – Jakemmarsh

+0

@MadProgrammer是正确的标记,我的“摇摆的接班人”语句来可能变成是错误的,但至少这是Oracle对Q6的预测“在JavaFX的替代摇摆..?” Res“是的。但是,Swing将保持...“。请参阅[链接](http://www.oracle.com/technetwork/java/javafx/overview/faq-1446554.html#6)。JavaFX版本1是一种脚本语言,因此对现有Swing程序员的广泛用户群没有吸引力,包括我自己在内,JavaFX 2+有更好的成功机会,因为它正在成为Java的一个组成部分。 – Skjalg

+0

@Skjalg并不是说这是一个糟糕的技术,这只是另一种选择;) – MadProgrammer

2

建立你挥杆的愿望将是一个真正的挑战的样子。它可以完成,但不能使用CSS,而不是没有相当多的工作。由于JavaFX支持CSS并具有媒体播放器,因此我会考虑使用此新框架。您可以get started here.

我最近建立了一个小的JavaFX应用程序,我曾与现场生成器,图形工具,现在与Netbeans的集成,以帮助开发人员创建UI上场的机会。在修改CSS文件时,UI将在场景构建器中更新。我们设计的实际元素与我们在HTML中使用的元素不同。以下是我用于我的应用程序的CSS文件;您可以查看&运行我的应用程序mathteamhosting.com

请记住,如果您使用的是32位浏览器,则需要32位版本的Java才能将其作为小程序运行。

.root { 
    display: block; 
} 

.text-input { 
    -fx-font-size: 18px; 
    -fx-font-weight: bold; 
} 

.text-field { 
    -fx-font-size: 18px; 
    -fx-font-weight: bold; 
} 

.label { 
    -fx-font-size: 18px; 
} 

.button { 
    -fx-font-size: 15px; 
    -fx-font-weight: bold; 
    -fx-text-fill: black; 
    -fx-background-color: linear-gradient(#0000ff, #ffeeff); 
} 
#note { 
    -fx-font-size: 15px; 
} 

#heading { 
    -fx-text-fill: #000099; 
    -fx-font-size: 18px; 
    -fx-font-weight: bold; 
}