论坛首页 Java企业应用论坛

Swing第三刀:做套ERP,要配得上我的登录界面!

浏览 73061 次
该帖已经被评为精华帖
作者 正文
   发表时间:2010-07-13  
yedaya 写道
“对窗体上的组件安装这一listener,就可以对窗口中任意元素进行拖拽,直接拖动窗体四处晃悠了。”
具体怎么装?能不能就那个红色的方框演示一下。
比较愚钝,请明示!!谢谢。

请参考FreeLoginUI.java中的132行:
logoLabel.addMouseListener(moveWindowListener);
        logoLabel.addMouseMotionListener(moveWindowListener);
0 请登录后投票
   发表时间:2010-07-13  
xiaozhonghua 写道
yedaya 写道
“对窗体上的组件安装这一listener,就可以对窗口中任意元素进行拖拽,直接拖动窗体四处晃悠了。”
具体怎么装?能不能就那个红色的方框演示一下。
比较愚钝,请明示!!谢谢。

请参考FreeLoginUI.java中的132行:
logoLabel.addMouseListener(moveWindowListener);
        logoLabel.addMouseMotionListener(moveWindowListener);

哦,明白了,我没有添加第二个事件,出来了,谢谢。
0 请登录后投票
   发表时间:2010-07-16  
雪花报错:
[Exception in thread "main" java.lang.IllegalArgumentException: Width (0) and height (0) cannot be <= 0/code]

加上frame.setBounds(0, 0, 1, 1);后就好了。


期望第四刀。源码什么时候出出来呀。  以前做的是web,看了你的贴后感觉不错,想看看你代码的规划,风格。
0 请登录后投票
   发表时间:2010-08-30   最后修改:2010-08-30
  根据官方导引http://java.sun.com/developer/technicalArticles/GUI/translucent_shaped_windows/和http://www.docjar.com/docs/api/com/sun/awt/AWTUtilities.html,类AWTUtilities对于窗体透明性的支持有3个枚举常量,并且"The constants PERPIXEL_TRANSPARENT, TRANSLUCENT, PERPIXEL_TRANSLUCENT represent shaping, simple translucency, and per-pixel translucency respectively."。
  其实,类AWTUtilities只是想知道窗体Bounds范围所有点的alpha值。它提供了3种不同的设置方法:1是利用Shape设置点全透明(0.0f,如果在Shape边缘或Shape内)或全不透明(1.0f,在Shape外);2是设置点为同一个透明度(例如可以设置为0.8f);3是自己手动设置每一个点的alpha值(譬如官方导引中示例的是GradiantPaint)。如下所示。方法1演示了一个字母'T'的Shape。

  这3种方法不分好坏,取决于自己的使用目的。方法1比较适用于Shape比较整齐(因为没有anti-alias),譬如实现一个“品”字形的窗体,也比较适用于Shape很容易获得的情况,譬如一个字符串在特定Font下的显示。方法2适用于窗体透明性很统一的时候。方法3适用于自定义,例如使用一张png图片指出各个点的alpha值。但是应当注意,只要AWTUtilities.setWindowOpaque(frame, false),无论你设置任何子组件的Opaque与否,系统都会以Opaque==false处理,这样就会导致JComponent的背景不会被绘制。
  所以lz登录界面采用第3种方法是最好的。不过题外话说一句,即使使用方法1,如下办法也可以正确绘制图片的Shape。即逐行扫描每个点的alpha值,连在一起的不为0.0f的点可以画一个Rectangle,然后将所有的Rectangle合并成一个Area。避免了lz提到的算法的“边缘必须是连续的,甚至必须是‘外凸’的”的缺陷。另外,方法3中使用的图片,我在Photoshop做处理的时候,一个点的不透明度&填充<5%则在我的Java实验中被当成完全透明(alpha=0.0f),反之就有alpha>0.0f。下面一个例子使用了这样一个“回”字型的png,里面空白的不透明度是0%,外圈空白的不透明度是5%,虽然他们视觉上几乎辨别不出来区别,但是用鼠标点一点就知道了,

(不过贴到论坛上 怎么看不出来是透明了  )
  配套使用的Java代码:
import java.awt.Color;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import com.sun.awt.AWTUtilities;

public class TranslucentFrameDemo extends JFrame
{
	private static final long serialVersionUID = 3878450094604602368L;

	TranslucentFrameDemo()
	{
		setUndecorated(true);
		setSize(400, 400);
		AWTUtilities.setWindowOpaque(this, false);
		final JLabel label = new JLabel(new ImageIcon("d:\\clip.png"));
		label.setBackground(Color.BLACK); // actually won't work
		add(label);
	}

	public static void main(final String[] args)
	{
		SwingUtilities.invokeLater(new Runnable()
		{
			@Override
			public void run()
			{
				new TranslucentFrameDemo().setVisible(true);
			}
		});
	}
}


  另外应当注意的是,不是所有的OS——例如linux的CentOS发行版——都支持AWTUtilities带来的窗体透明。应该在使用窗体透明的方面前加入检测代码,如官方示例中做的那样。
  关于实现原理,由于在不规则的窗体中使用"Alt+Space"快捷键依然有效,依然可以设置AlwaysOnTop(true)并且确实一直在顶端,并且其绘制过程中使用了sun.awt.windows.WWindowPeer和BufferedImage类(参考lz把窗体设为很大导致溢出),我倾向于认为这样的不规则窗体依然使用了OS的window作为对等的peer,只是JVM先把不规则窗体中的所有内容先绘制到BufferedImage上,再向OS的window绘制Image,这个过程和Swing正常状态下直接使用window的绘制上下文绘制Swing组件还是略有不同的。不过我对Windows的底层编程实在不熟悉,也仅局限于这样猜测。为什么Windows的window现在可以是不规则、透明的?为什么以前不能?底层的实现原理是什么?关于这点疑问很希望和大家交流相关资料或见解!:)
  再另外,半透明的Jcomponent绘制可以参考:
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;


public class TanslucentJButtonDemo extends JFrame
{
	TanslucentJButtonDemo()
	{
		setSize(300, 300);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLayout(null);
		getContentPane().setBackground(Color.YELLOW);
		MyButton b = new MyButton();
		b.setBounds(100,50,100,100);
		add(b);
	}
	public static void main(String[] args)
     {
	     SwingUtilities.invokeLater(new Runnable()
		{
			@Override
			public void run()
			{
				try {  
					    for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {  
					        if ("Nimbus".equals(info.getName())) {  
					            UIManager.setLookAndFeel(info.getClassName());  
					            break;  
					        }  
					    }  
					} catch (Exception e) {  
					    // If Nimbus is not available, you can set the GUI to another look and feel.  
					}  
				new TanslucentJButtonDemo().setVisible(true);
			}
		});
     }
}

class MyButton extends JButton
{
	MyButton()
	{
		super("Push Me!");
		setOpaque(false);	// critical! Make this line a comment and guess what happens.
	}
	
	@Override
	public void paint(Graphics g)
	{
		Graphics2D g2 = (Graphics2D) g;
		Composite com = g2.getComposite();
		g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
	     super.paint(g2);
	     g2.setComposite(com);
	}
}

  选择在Jcomponent里面覆盖paint而不是在某个UIDelegate里覆盖,是因为这样可以无论什么LAF,都可以获得渲染后的半透明组件。

  感谢lz的尝试和工作!向老汪致敬! 
  • 大小: 4.6 KB
  • 大小: 3.9 KB
0 请登录后投票
   发表时间:2010-09-04  
另外,通过尝试,可以由以下小技巧实现用Shape定义的Frame的antilias。效果对比:



import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Transparency;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import com.sun.awt.AWTUtilities;

public class AntiliasShapedFrame extends JFrame
{
	/**
      * 
      */
	private static final long serialVersionUID = 3390474537469218502L;
	private Shape s = null;
	private int width = 0;
	private int height = 0;

	AntiliasShapedFrame()
	{
		initShape();
		setUndecorated(true);
		AWTUtilities.setWindowOpaque(this, false);
		setSize(width, height);
		setContentPane(new MyPanel());
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLocationRelativeTo(null);
	}

	private void initShape()
	{
		final GlyphVector vector = new Font(Font.SANS_SERIF, Font.BOLD, 100).createGlyphVector(new FontRenderContext(null, false, false),
		          "Hello, World!");
		s = vector.getOutline();
		width = (int) (s.getBounds().getWidth());
		height = (int) (s.getBounds().getHeight());
	}

	private BufferedImage createImg()
	{
		final BufferedImage img = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration()
		          .createCompatibleImage(width, height, Transparency.TRANSLUCENT);
		final Graphics2D g2 = img.createGraphics();
		g2.setComposite(AlphaComposite.Clear);
		g2.fillRect(0, 0, width, height);
		g2.translate(-s.getBounds().getX(), -s.getBounds().getY());
		
		g2.setComposite(AlphaComposite.Src);
		//g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2.setPaint(new GradientPaint(0, 0, Color.RED, width, height, Color.YELLOW));
		g2.fill(s);
		g2.dispose();
		return img;
	}

	public static void main(final String[] args)
	{
		SwingUtilities.invokeLater(new Runnable()
		{
			@Override
			public void run()
			{
				new AntiliasShapedFrame().setVisible(true);
			}
		});
	}

	class MyPanel extends JPanel
	{
		private static final long serialVersionUID = 1034001230923305745L;

		@Override
		protected void paintComponent(final Graphics g)
		{
			super.paintComponent(g);
			((Graphics2D) g).drawImage(createImg(), 0, 0, null);
		}
	}
}

  • 大小: 107.9 KB
0 请登录后投票
   发表时间:2010-09-04  
sun的论坛里有不少swing的牛人,基本上任何问题在那里都可以找到答案。但某些人对oop不太精通,有时候和他们很难沟通。
0 请登录后投票
   发表时间:2010-10-19  
ubuntu10.10下
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: The window must use a translucency-compatible graphics configuration
at com.sun.awt.AWTUtilities.setWindowOpaque(AWTUtilities.java:377)
at free.FreeLoginUI.init(FreeLoginUI.java:96)
at free.FreeLoginUI.<init>(FreeLoginUI.java:89)
at free.FreeLoginUI$4.run(FreeLoginUI.java:207)
0 请登录后投票
   发表时间:2010-11-02  
强大的LZ,正在学习swing,感谢分享
0 请登录后投票
   发表时间:2010-11-03  
xiangkun 写道


为什么我的这里运行出来是这样的呢?

Windows Xp下的.


已经很漂亮了哦
0 请登录后投票
   发表时间:2010-11-05  
楼主,感谢你的奉献!刚学Swing。你的文章对我帮助很大!谢谢
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics