博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
FireFox Personas for the NetBeans Platform
阅读量:6371 次
发布时间:2019-06-23

本文共 7443 字,大约阅读时间需要 24 分钟。

http://blogs.oracle.com/geertjan/entry/firefox_personas_for_the_netbeans

————————————————————————————————————————————————————————————————————————

 

While thinking about , I received a great tip from NetBeans Platform window system guru Stan Aubrecht:
There's a small API change in openide.windows module (see version 6.38 in core-main repo) which allows you to make most of the main window components non-opaque (menu bar, toolbars, slide bars, status bar etc), so you can provide your own JFrame window to be used as the main window and have a custom painted background in that frame. The custom painted image/gradient will be showing through the main window controls, just like when using personas in FireFox.

 To get the point, go to . "Personas are easy-to-use themes that let you personalize the look of your Firefox." The page shows you a bunch of different appearances for FireFox and, when you hover over any of them, the whole appearance of FireFox changes, as you can see here:

 

 Wouldn't it be cool if you could do the same thing in a NetBeans Platform application? Well, now you can. By "now" I mean "after NetBeans 7.0 Beta 2", i.e., this has not made it into Beta 2, you'll need to get a very recent daily build or just rebuild your local Mercurial check out, which is what I did today.

Here is the result of the code I will show below. When I mouse over one of the buttons in my Personas window, everything changes to reflect the colors displayed in the button:

 

 

 

Nice, right?

Here's how:

 

 

1. Get the right distribution of NetBeans IDE. I.e., if you are using NetBeans IDE 7.0 Beta 2 or anything before that, the code below will NOT work. You need something more recent, a daily build from yesterday, or rebuild your Mercural checkout.
2. Create a "PersonaButton", which reads its colors from a preference that will be set when the mouse enters the button, with a border that changes depending on whether the mouse enters the button or exits it:
public 
class PersonaButton 
extends JButton {
    
    
private 
final Color color1;
    
private 
final Color color2;
    
public PersonaButton(
final Color color1, 
final Color color2) {
        
        
this.color1=color1;
        
this.color2=color2;
        
        setPreferredSize(
new Dimension(130,100));
        
        addMouseListener(
new MouseAdapter() {
            @Override
            
public 
void mouseEntered(MouseEvent e) {
                NbPreferences.forModule(PersonaButton.
class).put("color1", Integer.toString(color1.getRGB()));
                NbPreferences.forModule(PersonaButton.
class).put("color2", Integer.toString(color2.getRGB()));
                setBorder(
new LineBorder(Color.RED,2));
            }
            @Override
            
public 
void mouseExited(MouseEvent e) {
                setBorder(
new LineBorder(Color.BLACK));
            }
        });
        
    }
    @Override
    
public 
void paintComponent(Graphics g) {
        Paint p = 
new GradientPaint(0, 0, color1, getWidth(), 0, color2);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setPaint(p);
        g2d.fillRect(0, 0, getWidth(), getHeight());
    }
    
}

3. Create a "PersonasTopComponent", which is where the user will select their persona by entering the button with their mouse:

...
...
...
private Color color1 = Color.RED;
private Color color2 = Color.BLUE;
public PersonasTopComponent() {
    initComponents();
    setName(NbBundle.getMessage(PersonasTopComponent.
class, "CTL_PersonasTopComponent"));
    setToolTipText(NbBundle.getMessage(PersonasTopComponent.
class, "HINT_PersonasTopComponent"));
    setLayout(
new MigLayout());
    
//
Here the buttons are hardcoded, but they could come from the layer file,
    
//
so that all of this could be pluggable, potentially...
    add(
new PersonaButton(Color.RED, Color.BLUE), "wrap");
    add(
new PersonaButton(Color.YELLOW, Color.GREEN));
    
final Preferences pref = NbPreferences.forModule(PersonaButton.
class);
    pref.addPreferenceChangeListener(
new PreferenceChangeListener() {
        @Override
        
public 
void preferenceChange(PreferenceChangeEvent evt) {
            
if (evt.getKey().equals("color1") || evt.getKey().equals("color2")) {
                String colorString1 = pref.get("color1", "-65536");
                String colorString2 = pref.get("color2", "-16776961");
                color1 = 
new Color(Integer.parseInt(colorString1));
                color2 = 
new Color(Integer.parseInt(colorString2));
                repaint();
            }
        }
    });
}
@Override
public 
void paintComponent(Graphics g) {
    Paint p = 
new GradientPaint(0, 0, color1, getWidth(), 0, color2);
    Graphics2D g2d = (Graphics2D) g;
    g2d.setPaint(p);
    g2d.fillRect(0, 0, getWidth(), getHeight());
}
...
...
...

 

4. Create a new JFrame which will be your application's main window, instead of the default one. That's another .

Nov 23 '10; API spec. version: 6.36; made by: saubrecht
When window system loads it checks for existing Frames (java.awt.Frame.getFrames()) and if there is a JFrame whose name is "NbMainWindow" then it is reused as the main window. Main menu, toolbars and content pane will be put into this existing JFrame. If there isn't such a JFrame instance then a new empty JFrame is created and used for the main window - the same way as before this change.
 

 

The JFrame's colors are set based on the preferences that you set via the JButtons above.

 

public 
class RootFrame 
extends javax.swing.JFrame {
    
private Color color1 = Color.RED;
    
private Color color2 = Color.BLUE;
    
public RootFrame() {
        
        setRootPane(
new CustomRootPane());
        initComponents();
        
        setName("NbMainWindow");
        
        
final Preferences pref = NbPreferences.forModule(PersonaButton.
class);
        pref.addPreferenceChangeListener(
new PreferenceChangeListener() {
            @Override
            
public 
void preferenceChange(PreferenceChangeEvent evt) {
                
if (evt.getKey().equals("color1") || evt.getKey().equals("color2")) {
                    String colorString1 = pref.get("color1", "-65536");
                    String colorString2 = pref.get("color2", "-16776961");
                    color1 = 
new Color(Integer.parseInt(colorString1));
                    color2 = 
new Color(Integer.parseInt(colorString2));
                    repaint();
                }
            }
        });
        
    }
    
static 
void init() {
        
new RootFrame();
    }
    
private 
class CustomRootPane 
extends JRootPane {
        @Override
        
public 
void paintComponent(Graphics g) {
            Paint p = 
new GradientPaint(0, 0, color1, getWidth(), 0, color2);
            Graphics2D g2d = (Graphics2D) g;
            g2d.setPaint(p);
            g2d.fillRect(0, 0, getWidth(), getHeight());
        }
    }
    ...
    ...
    ...

 

5. Finally, create a new ModuleInstall class, where you specify that the background of the main window should be customized (i.e., this is the tip with which this blog entry started) and initialize the JFrame, because that needs to happen somewhere, i.e., the JFrame needs to be initialized somewhere, otherwise it will not be part of the application:

public 
class Installer 
extends ModuleInstall {
    @Override
    
public 
void restored() {
        
try {
            UIManager.setLookAndFeel( 
new MetalLookAndFeel() );
        } 
catch( UnsupportedLookAndFeelException ex ) {
            Exceptions.printStackTrace( ex );
        }
        UIManager.put( "NbMainWindow.showCustomBackground", Boolean.TRUE);
        RootFrame.init();
    }
    
}

 

 

Why is MetalLookAndFeel used? That's because Stan told me: "It looks best under MetalLookAndFeel, otherwise the menu bar is painted using regular look and feel." That's an interesting comment, maybe somehow related to Henry's problems. Trying to figure out still why the menu bar is special, maybe someone can advise on this point?

Finally, best of all, thanks to the NetBeans Platform's module system, the FireFox Personas for the NetBeans Platform are... pluggable, like anything else in the NetBeans Platform. I.e., I foresee a future where contributors provide new personas (i.e., "skins") that would be loaded into a centralized Personas window. When moused over, the contributed persona would automatically update the main window components, as well as anything else you have specified.

 

 

 

 

 

 

 

 

 

 

转载地址:http://yeuqa.baihongyu.com/

你可能感兴趣的文章
Azkaban的Exec Server分析 31:FlowRunner如何推动Graph的前进
查看>>
Android切近实战(二)
查看>>
实施微服务,我们需要哪些基础框架?[转]---技术问题
查看>>
MyBatis-3.4.2-源码分析17:XML解析之bindMapperForNamespace
查看>>
ubuntu操作系统真机调试android问题
查看>>
MySQL权限更改示例及SQL语句练习
查看>>
linux下为php添加memcache扩展=>解决服务器集群session共享问题
查看>>
nginx反向代理缓存静态文件
查看>>
Yum服务器搭建实例
查看>>
nginx rails 详细站点配置入门教程
查看>>
EXAM-5试题与详解
查看>>
丹尼斯·里奇,那个给乔布斯提供肩膀的巨人
查看>>
图片上传前预览
查看>>
etcd集群的部署
查看>>
struts2标签库
查看>>
我的友情链接
查看>>
使用CDN 获取JS/CSS
查看>>
软件的架构与设计模式之模式的种类
查看>>
Java记录 -14- 面向对象之多态
查看>>
cefsharp mp3,mp4,cef 问题有偿解决
查看>>