2009年4月24日金曜日

The glass pane in Java


/**
* Glass pane class
* The glass pane is displayed overlap the content
* pane in the japplet or jframe. It can be set to
* visible while user want to temporarily disable
* their window.
*
* Usage:
*
* //In your frame's initialization, set the glass pane.
* this.setGlassPane(new GlassPane());
*
* //In your event, make the glass pane visible.
* this.getGlassPane().setVisible(true);
* new Thread(){
* public void run(){
* //Your program code
* ...................
* SwingUtilities.invokeLater(new Runnable(){
* public void run(){
* XXXX.this.getGlassPane().setVisible(false);
* }
* });
* }
* }.start();
*
*
*/
public class GlassPane extends JComponent implements MouseListener, KeyListener{
/** Serial version ID */
private static final long serialVersionUID = -5955027767708857008L;

/** Label to display message */
private JLabel lblmsg = null;
/** Glass pane's color */
private Color glassColor = null;

/**
* constructor
*
*/
public GlassPane(){
addMouseListener(this);
addKeyListener(this);
setOpaque(false);

//Get glass pane's color
Color base = UIManager.getColor("OptionPane.background");
glassColor = new Color(base.getRed(), base.getGreen(), base.getBlue(), 128);

setLayout(new GridBagLayout());

lblmsg = new JLabel("aaaaaaaaa");
lblmsg.setHorizontalAlignment(SwingConstants.CENTER);
lblmsg.setOpaque(true);

this.add(lblmsg);
}

//Mask mouse and keyboard event
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mousePressed(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
public void mouseClicked(MouseEvent e){}
public void keyPressed(KeyEvent e){e.consume();}
public void keyReleased(KeyEvent e){e.consume();}
public void keyTyped(KeyEvent e){}

/**
* Show or hide glass pane
*
*/
public void setVisible(boolean fl){
super.setVisible(fl);
if(fl){
requestFocusInWindow();
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
}else{
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}

/**
* Drawing glass pane's background
*
*/
protected void paintComponent(Graphics g){
g.setColor(glassColor);
g.fillRect(0, 0, getSize().width, getSize().height);
}
}

2009年3月26日木曜日

To update data from other db in oracle

UPDATE TABLEA A SET (COLA, COLB)=(SELECT B.COLA, B.COLB FROM TABLEB B WHERE B.COL1=A.COL1 AND B.COL2=A.COL2 AND B.COL3='XXX') WHERE EXISTS (SELECT 'Z' FROM TABLEB B WHERE B.COL1=A.COL1 AND B.COL2=A.COL2 AND B.COL3='XXX') AND A.COL3='YYY';

2009年3月23日月曜日

Two way to delete file in vba macro

Method 1: Only works in Excel

 

Option Explicit

 

Public Sub killSelf()


   With ThisWorkbook

        .Saved = True

        .ChangeFileAccess xlReadOnly

        Kill .FullName

        .Close

    End With

End Sub

 

 

Method 2: Works in normal vb and vba, but need administrator's authority with windows2000 or over.

 

Option Explicit

 

Private Declare Function MoveFileEx Lib "kernel32" Alias "MoveFileExA" (ByVal OldFilename As String, ByVal NewFileName As String, ByVal nWord As Long) As Long


Private Const MOVEFILE_DELAY_UNTIL_REBOOT = &H4

Private Const MOVEFILE_REPLACE_EXISTING = &H1

Private Const MOVEFILE_DELAY_AND_REPLACE = MOVEFILE_DELAY_UNTIL_REBOOT + MOVEFILE_REPLACE_EXISTING

 

'Deletes the file szSource after reboot, use full path names

Public Sub DeleteAfterReboot()

    Call MoveFileEx(ThisWorkbook.FullName, vbNullString, MOVEFILE_DELAY_AND_REPLACE)

End Sub

2009年3月19日木曜日

Change IME in web page

  How to change IME in web page bothered us for a long time. Note I means change IME and not IME mode. IME mode can be changed in IE by setting styles which like style="ime-mode:active". But how to change IME? I have two IME in my windows xp. One is Microsoft IME Standard 2003, and one is Google IME. In the normal cases I use Microsoft IME Standard 2003 to input datas and in some special cases I need to use Google IME. It seems there is no way to change IME with Java applet or Javascript. IME is obviously depending on the system, so I think maybe JNI(Java Native Interface) is the only way. But what windows api should I use become an another problem. I used ActivateKeyboardLayout with flag KLF_SETFORPROCESS at first and it worked well under jre1.5. But when jre was upgraded to 1.6u10, it no longer worked because Java Plug-In's architecture has been substantially redesigned. In the release note of jre 6u10 it said "Rather than executing applets in a Java virtual machine (JVM) instance which is embedded in the web browser's process, the JVM instance which executes the applet is now a separate process from the web browser." It can be found in the url: http://java.sun.com/javase/6/webnotes/6u10/plugin2/version-selection/index.html It means before jre 1.6, when I used ActivateKeyboardLayout, it changed the applet's IME. Because the applet is embedded in the web browser's process, so web browser's IME was also changed. But since 1.6u10 the applet's process is different to the web browser's so ActivateKeyboardLayout changed the applet's IME and could not change the web browser's. I googled the solution for a long time and this time I could not find the answer, but I got a edification from them. PostMessage is used to post message to the window and if I can post the IME change message to the web browser's window, whether applet's process is same to web browser or not, IME will be changed. And a bit of test codes proved that this is the right way. Use PostMessage with WM_INPUTLANGCHANGEREQUEST, the IME has been changed successfully.

  To get keyboard layout handle, use the function below:
JNIEXPORT jlong JNICALL Java_XXXX_getImeHkl(JNIEnv *env, jobject obj){
    HKL hkls[100];
    HKL hklGgl = NULL;
    UINT nCount, i;
    long lLangId;

    //get the keyboard layout list
    memset(hkls, '\0', sizeof(hkls));
    nCount = GetKeyboardLayoutList(100, hkls);
    //find the handle of Google IME
    for(i=0; i<nCount; i++){
        memset(szName, '\0', sizeof(szName));
        ImmGetDescription(hkls[i], szName, 200);
        if(strcmp(szName, "Google IME's Name") == 0){
            hklGgl = hkls[i];
            break;
        }
    }

    return (long)hklGgl;
}

  To change the IME, use the function below:
JNIEXPORT void JNICALL Java_XXXX_changeIme(JNIEnv *env, jobject obj, jlong lHkl){
//    ActivateKeyboardLayout((HKL)lHkl, KLF_SETFORPROCESS);
    HKL curHkl;
    HKL hkl = (HKL)lHkl;
    HWND hwnd = GetForegroundWindow();
    curHkl = GetKeyboardLayout(GetWindowThreadProcessId(hwnd, NULL));
    if(curHkl != hkl){
        PostMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, INPUTLANGCHANGE_SYSCHARSET,(LPARAM)hkl);
    }

    return;
}

Java can't get home directory correctly

The user's home directory which is got by Java is different to the real user's home directory in windows xp. When using System.getProperty("user.home") to get home directory in java, you will get the path which contains the desktop folder. So if your desktop is not at the default position, you can't get the real home directory in windows xp. For example, you cut your desktop folder from the default path "C:\Documents and Settings\{user's id}", and paste it to the path "D:\users\{user's id}". Now java's System.getProperty("user.home") will give you the path "D:\users\{user's id}". And if you use System.getenv("USERPROFILE") to get the home directory from envionment variables, you will get the path "C:\Documents and Settings\{user's id}". So when getting home directory by java in windows xp, you must notice which folder is your wanted. I didn't notice it when I tried to get the application data folder. I used System.getProperty("user.home") concating "/Application Data" at first. It worked well in most cases and failed on one computer only because desktop of it is not at the default position. Finally I changed to use System.getenv("AppData") and then everthing is working well.

2009年3月17日火曜日

While pdf file can't be displayed in IE

The customers have updated their computers and then they found pdf can't be displayed by IE6 from our web system. When clicked the button in a webpage, an ie window with pdf file content in it would be opened before updating. And now the opened window will be closed as quickly as it opened. I googled it for a long time and finally found the solutions. First, in the internet option there is an advanced setting which prevents saving content from encrypted page. You can find it in the Advanced tab as 'Do not save encrypted page to disk' at Security group. The customers connected our web system using https and they checked this option, so pdf file is prevented to save on the disk after IE downloaded it and therefore acrobat can't open the pdf file. Uncheck this option is the first step for the solution. Second, try to open pdf again, and if it still can't be displayed, check the settings of your security. In the internet option click the 'Security' tab and click the 'customize level' button. This will open 'Security Settings' window. In this window you can find the setting of 'show dialog automatically when downloading files' at the 'Download' group. Enable this option and then a warning dialog will be displayed when you attempt to open a pdf file. Uncheck the option 'Always warn while trying to open a file of this type' before click the 'Open' button on the warning dialog. OK, now pdf file will be displayed in IE automatically without a warning dialog being displayed. By the way, if you want to restore the warning dialog, just delete the key from registry under 'HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\AttachmentExecute\{0002DF01-0000-0000-C000-000000000046}' which name is 'AcroPdf.Pdf.1'.