Monday, July 28, 2008

Retreiving and sending Hotmail email from Gmail

I had a Hotmail account years before Gmail was around, and I still keep it around just in case I get an important email there. I tried to use Gmail's "Get mail from other accounts" feature, but it always said "connection timed out". I had just assumed Hotmail offered POP3 - it doesn't. I found a helpful article on LifeHacker to get around this issue, but the software they mention is not a free service.

But, buried in the comments is a link to the "GetMail for Hotmail" Windows service. That link, however, sends you to the vendor's Web site, which wants you to sign up for a free trial of some other service in order to download the software. But, this link will let you download it with no strings attached.

You do have to enter your Hotmail password so that it can retreive the mail, which may be a deal-breaker for some. To be safer, I changed my Hotmail password to make sure it doesn't match any other service I use. I'm also confident that I don't use this account for any service I use, though that still doesn't technically make me 100% protected.
I'm also keeping an eye on it from a network perpective to make sure it's not trying to do anything it's not supposed to. I may actually attempt to write my own simple version of this some day just for the extra piece of mind. The program also is a resource hog, so you don't want have it set to fetch mail too often.

It does work well, otherwise, though. I've got mail set up to go directly to my Gmail archive (Settings --> Filters), and labeled with "Hotmail", so it's separate from my regular Gmail mail. I also set up my account under "Settings --> Send mail as" so that I can have email sent as if it came from Hotmail.

If everything keeps working well, I'll be very glad to not have to log into Hotmail anymore.

Thursday, July 24, 2008

SQL Server 2000 not deleting backups

I'm sure there could be a lot more reasons for backup deletions failing than this, but detaching a database that was set to "offline" fixed the problem for me. No other error messages I could find - luckily I realized the problem started around the time we took that db offline, so it didn't take too long to troubleshoot.

Monday, July 14, 2008

JTabbedPane with close button that sets the tab title correctly

Java 6 includes the abilility to add a component (like a "x" to close the tab) to a tab pane, and Alexander Potochkin, has elegantly put together a "ButtonTabComponent" class to easily handle this.

I've made just a few changes to get the "x" to look more like the "x"'s on the rest of my application, and most importantly for me, to set the title of the JTabbedPane so that calling getTitleAt(tabPosition) doesn't return an empty string, since this is now handled completely by the ButtonTabComponent class. BTW, I'm mixing regular tabs with tabs that can be closed, so I want to be able to just have to call one method to check what each's title is, i.e.:

int existingTabPosition = 0;
int tabCount = tabbedPane.getTabCount();
for(int i = 0; i < tabCount; i++) {
String thisTabTitle = tabbedPane.getTitleAt(i);
if(thisTabTitle.equals(menuSelectedTabTitle)) {
existingTabPosition = i;

if(existingTabPosition != 0) {
//report already exists - just force focus to it
} else {
//no report exists by this name - add new tab
int newTabPosition = tabbedPane.getTabCount() - 1;

tabbedPane.setTabComponentAt(newTabPosition, new ButtonTabComponent(menuSelectedTabTitle, tabbedPane));

Here's my updated "paintComponent" method of the TabButton inner class:
      //paint the "x" and update the title
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Stroke stroke = g2.getStroke();

//shift the image for pressed buttons
//changed by DG
//if(!getModel().isPressed()) {
// g2.translate(-1, -1);

g2.setStroke(new BasicStroke(2));
if(getModel().isRollover()) {
Color highlight = new Color(0, 51, 153); //dark blue - changed by DG
int delta = 5; //changed by DG
g.drawLine(delta, delta, getWidth() - delta - 1, getHeight() - delta - 1);
g.drawLine(getWidth() - delta - 1, delta, delta, getHeight() - delta - 1);

//NOTE: only needed if button pressed in effect is used above
//changed by DG
//leave the graphics unchanged
//if(!getModel().isPressed()) {
// g.translate(1, 1);

//add the title here - added by DG
int i = pane.indexOfTabComponent(ButtonTabComponent.this);
pane.setTitleAt(i, label.getText());
I assume the title is set here for a specific reason, though my next experiment will be to remove the title from here and add it back to the JTabbedPane - though the way it is might actually be a bit nicer to work with. Alternatively, you can set both at the same time - it works without problems, but it seems like bad form to have to manually set the same thing twice.

Monday, July 7, 2008

Apache Commons

I had forgotten that the first Java book I read, Bruce Eckel's "Thinking In Java", highly recommended using Apache Commons if you found that the core language didn't contain something you expected to be there. The "Commons" are vast set of libraries that improve and add to the core Java language, and can be a huge time saver.

My goal this week is to read all the Commons' user guides to get familiar with its capabilities.

Tuesday, July 1, 2008

JTextArea setEnabled strangeness (Java Swing)

NetBeans 6.1 automatically wraps a JScrollPane around a JTextArea, and handles all the details of setting it up nicely. But, if you need to work with all your components at once (i.e. to tick the "setEnabled" property on each), you'll find the following code works on everything but the JTextAreas (and probably all other nested components):
for(Component component : ProjectPanel.getComponents()) {
I haven't found a good way around this yet, as the following addition to the loop fails as well:
//use reflection to get the class type
if(component.getClass().equals(JScrollPane.class)) {
JScrollPane scrollPane = (JScrollPane)component;

for(Component subComponent : scrollPane.getComponents()) {
Debugging reveals that the the JTextArea isn't seen as a component here (things like the scroll bar and viewport are, though). getComponents() doesn't loop over children, so maybe this does work two or three levels deeper, but that's getting a bit ridiculous.

Until I figure out a better way, I'm setting the values explicitly using the following method:
The "setBackground" method is needed here (at least on Windows XP using the "Classic" theme), as the background isn't automatically set to the disabled color when setEnabled is set to "true". Most other components automatically handle this for you. This also means when you re-enable it, you need to set it back to the default enabled color:
BTW, I found a good article on using UIManager here that explains how to use and manipulate UI settings.

In any case, I found an official Java bug report from 1998 concerning what appears to be the exact enabled/disabled problem I ran into - the bug's status is "6-Fix Understood, request for enhancement". Though the suggested fix actually didn't work for me...