Coping with GridBagLayout produced by Netbeans and modifying generated code to get what I couldn't make Netbeans give me - netbeans

I have no question, just sharing 3 days of frustration and ultimate success.
The above is what I got from Netbeans using its GridBagLayout mode. Below is what I wanted.
I couldn't get what I wanted within a reasonable time using Netbeans, so I thought I would be able to cut, paste, and modify the generated code to make the form look like what I want.
I was right and the time spent in getting what I wanted was minimal, using the Netbeans "outline" that I started late last night.
Here's my code:
public class DoThis extends JFrame {
... (variable declarations removed)
public DoThis() {
initComponents();
}
private void initComponents() {
GridBagConstraints gridBagConstraints;
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new GridBagLayout());
pnlFileStuff = new JPanel();
pnlFileStuff.setBorder(BorderFactory.createEtchedBorder());
pnlFileStuff.setLayout(new GridBagLayout());
lblRootNode = new JLabel("Root node:");
gridBagConstraints = new GridBagConstraints();
pnlFileStuff.add(lblRootNode, gridBagConstraints);
txtRootNode = new JTextField("C:\\Users");
gridBagConstraints = new GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.ipadx = 520; // One key
gridBagConstraints.anchor = GridBagConstraints.WEST;
pnlFileStuff.add(txtRootNode, gridBagConstraints);
btnBrowse = new JButton("Browse...");
gridBagConstraints = new GridBagConstraints();
pnlFileStuff.add(btnBrowse, gridBagConstraints);
lblFilenamePattern = new JLabel("Filename pattern:");
gridBagConstraints = new GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
pnlFileStuff.add(lblFilenamePattern, gridBagConstraints);
txtFilenamePattern = new JTextField("*.*");
gridBagConstraints = new GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.ipadx = 250; // the other key
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
gridBagConstraints.anchor = GridBagConstraints.WEST;
pnlFileStuff.add(txtFilenamePattern, gridBagConstraints);
getContentPane().add(pnlFileStuff, new GridBagConstraints());
pack();
}
public static void main(String args[]) {
invokeLater(new Runnable() {
public void run() {
new DoThis().setVisible(true);
}
});
}
}
As it turns out, I only needed to do one additional thing in Netbeans--only one of the ipadx instances labeled "key" in the code. Sort of embarrassing to admit. And I didn't have to!
Just call it a learning experience that I decided to share, for better or worse. I think some newbie might profit from this post.
"Lessons" "learned":
(1) It's hard as heck to use Netbeans in "GridBagLayout mode". It's too far from WYSIWYG and far from intutitive. (This from a guy who had never used GridBayLayout and had never read about it until several days ago.) As one link suggested by S.O. that I followed stated, "Unfortunately, GridBagLayout is infernally awkward and error-prone to use." No argument here.
(2) Spending enough time struggling with Netbeans was worth it, in that, without it, it was almost impossible to read textbooks and tutorials and get anything close to desired outcome (YMMV).
(3) The code Netbeans generates in "GridBagLayout mode" is MUCH closer to human-written code than the usual incomprehensible hundreds of lines of krazy kode (that it generates in "free design" mode), which is virtually impossible to follow, let alone cut, paste, and edit (though I've had minimal success doing so). (Never again.)
(4) The generated GridBagLayout code is reasonably easy to cut, paste, and edit to generate the desired outcome (given that it was in the ballpark to begin with, and ignoring ample frustration with its quirks).
Most importantly (for ME), I finally feel free from Netbeans and may be on the way to developing some skill at writing GUI code from scratch, something I've avoided like the plague for months!!

I would be remiss not to revisit this thread and state that learning how to use GridBagLayout without Netbeans GUI builder is attainable by anyone. In less than a week of learning and getting help and advice from SO, I have finally arrived at creating a GUI that (unlike that generated by Netbeans) is easily editable and extendable--because I wrote the code by hand. The GUI that I'd been using and bugging SO with questions about for months (e.g., how to keep display from flashing during execution, which led to SwingWorker and other complications) has been replaced by the one below, which I created in a night and "perfected" the next day (today):
I'm not bragging; far from it. I barely know squat. Like "perfected" means "got output, and it doesn't flash, and it's readable, but it's ugly as sin."
Just providing hope for other newbies, I hope.

Related

How can I get Excel to close when I'm done with it?

This is in a COM API Word AddIn. And yes normally Hans Passant's advice to let .NET clean everything up works.
But it is not working for the following case - and I have tested running normally (no debugger) and have narrowed it down to this specific code:
private Chart chart;
private bool displayAlerts;
private Application xlApp;
Chart chart = myShape.Chart;
ChartData chartData = chart.ChartData;
chartData.Activate();
WorkbookData = (Workbook)chartData.Workbook;
xlApp = WorkbookData.Application;
displayAlerts = xlApp.DisplayAlerts;
xlApp.Visible = false;
xlApp.DisplayAlerts = false;
WorksheetData = (Worksheet)WorkbookData.Worksheets[1];
WorksheetDataName = WorksheetData.Name;
WorksheetData.UsedRange.Clear();
// ... do a bunch of stuff including writing to the worksheet
xlApp.DisplayAlerts = displayAlerts;
WorkbookData.Close(true);
I think the problem is likely Word is giving me this workbook and so who knows what it is doing to instantiate Excel. But even after I exit Word, the Excel instance is still running.
Again, in Word (not Excel), accessing a chart object to update the data in the chart.
COM objects need to be released completely, else "orphaned" objects can keep an application in memory, even after the code that called it goes out-of-scope.
This particular case may be special (compared to other code you've used previously) due to using xlApp. By default, an Excel Application object is not needed or used when manipulating charts with the object model introduced in Office 2007 (I think it was). It's used in the code in the question in order to hide the Excel window, which is visible by default (and by design). But the object model isn't designed to handle cleaning that up - it assumes it isn't present...
In my tests, the object is released correctly when (referencing the code in the question):
All Excel objects are set to null in the reverse order they are instantiated, being sure to quit the Excel application before trying to set that object to null:
WorksheetData = null;
WorkbookData = null;
xlApp.Quit();
xlApp = null;
Then, C# has a tendency to create objects behind the scenes when COM dot-notation is used - these don't always get cleaned up (released) properly. So it's good practice to create an object for each level of the hierarchy being used. (Note: VBA doesn't have this problem, so any code picked up from a VBA example or the macro recorder needs to be re-worked in this respect.) From the code in the question this affects WorksheetData.UsedRange.Clear();
Excel.Range usedRng = WorksheetData.UsedRange;
usedRng.Clear();
usedRng = null;
And the standard clean up, to make sure everything is released at a predictable moment:
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
When things like this crop up, I always refer to ".NET Development for Office" by Andrew Whitechapel. That's really "bare bones" and some of it no longer relevant, given the changes to C# over the years (to make it "easier to use" in the way VB.NET is "easier"). But how COM interacts with .NET hasn't changed, deep down...

Eclipse removing white spaces when saving

I have a big issue. I develop in eclipse ide environment, mostly on windows but also on linux. This seems to be a general issue.
Before I save my project on eclipse I have certain spaces between functions or in the code somewhere. I don't want to reformat the code that is in place.
However, every single time I try to save my project. Those spaces disappear, and I cannot find the place where I should change this auto-formatting in my eclipse properties.
Please see example bellow:
First of all I don't touch the code but I receive it as bellow and have to make modifications elsewhere. So at the initial state of my file I have somewhere in the code two functions [functionOne, functionTwo]. Those two functions are separated by a new line [NL] and 6 spaces. The problem appears when I save my project and as you can see the two functions are not separated anymore by the same number of spaces.
Before saving my project:
public void functionOne(){
int i = 0;
while(i<150)
{
//blabla...
}
}
NL:123456
public void functionTwo(){
int i = 0;
while(i<150)
{
//blabla...
}
}
After saving my project:
public void functionOne(){
int i = 0;
while(i<150)
{
//blabla...
}
}
NL:1
public void functionTwo(){
int i = 0;
while(i<150)
{
//blabla...
}
}
I'm starting to be sick of this issue and really need help to solve this.
Not forgetting to mention that absolutely no "Save actions" is enabled!
I don't see anything on my format options neither, but I could be wrong.
Could someone please help me to find a solutions to this problem?
Best regards,
Greg
So that wasn't the "Save actions" but some plugin that I was using. Didn't had the time to check which one it is I just uninstalled the rarely/unused once. And for the moment it seems to work. I'll check later if the problem remains/reappears.
Thanks for your help.
Best regards,
Gregory

Rendering a single point in a JFreeChart based on the current Value of a Slider

I'm not yet as much into Java as I'd like to be, so I find my current task to be quite a bit challenging:
A chart showing data gathered in another class.
A slider whose end value is determined by the last entry of in the dataset used in the chart.
The playbutton currently doesn't do anything except letting the slider tick in steps of 5 until it is paused again.
My problem right now is: I am supposed to highlight one item at a time in the chart based on which value the slider currently shows.
And to be honest... I'm not yet used to renderers yet.
If I understood it correctly I would need to use
renderer.drawItem(java.awt.Graphics2D g2,
XYItemRendererState state,
java.awt.geom.Rectangle2D dataArea,
PlotRenderingInfo info,
XYPlot plot,
ValueAxis domainAxis,
ValueAxis rangeAxis,
XYDataset dataset,
int series,
int item,
CrosshairState crosshairState,
int pass)
but I am totally inexperienced with as well the method as its arguments and got no idea how to initialize them.
I mean... I got a plot, a dataset, and 2 series from the chart, I also suggest "item" would be the index of the item to highlight in the series, which I could convert from the slider-value.
Unfortunately plaguing google about it turned out to be rather frustrating since all I got was the very code I posted above on about 50 different pages (I gave up after).
I would like to know ... first of all if I am even about to use the correct method and, as ashamed as I am to ask like this... how to use it.
Well... looking forward to some answers and... thanks in advance.
Well, I now solved my problem in a different way than I intended to but it works out just fine for me.
Instead of highlighting a point in the curves I just simply add a Domainmarker that would adjust based on the value the slider currently shows.
class1 TestSlider
private HashSet<SliderListener> sliderListenerSet = new HashSet<SliderListener>();
public void addSliderListener(SliderListener Listener){
sliderListenerSet.add(Listener);
}
slider.addChangeListener(this);
public void stateChanged(ChangeEvent e) {
// TODO Auto-generated method stub
JSlider source = (JSlider)e.getSource();
if (!source.getValueIsAdjusting()) {
fireSliderChanged();
}
}
public void fireSliderChanged(){
for (SliderListener currentListener : sliderListenerSet)
currentListener.sliderValueChanged();
}
class2 SliderListener
public interface SliderListener extends EventListener{
public void SliderValueChanged();
}
class3 Chart
Marker marker = new ValueMarker(0);
plot.addDomainMarker(marker); //so that it would be there at the beginning
TestSlider ts = new TestSlider();
ts.addSliderListener(new SliderListener(){
#Override
public void sliderValueChanged() {
plot.removeDomainMarker(marker); //I only want one of them at a time - the one with the value the slider is currently showing so remove the old one...
marker = new ValueMarker(ts.slider.getValue());
plot.addDomainMarker(marker); // ... and add the one with the new value
}
});
}
I tried to keep it as short and universal as I could and I hope I didnt cut out anything important.
Well, I'm still new to this site, so... in case I did a mistake somewhere feel free to tell me.

OpenXML: Issue adding images to documents

Up until now, this block of code has been using to build documents with text for several months with no snags. I am now trying to dynamically add images. I've spent about two days staring at code and researching and am at an end. I suspect the issue is that relationships are not being created (more details below.) Maybe not?
//set stuff up...
WordprocessingDocument doc = WordprocessingDocument.Open(fsPat, true, new OpenSettings(){
AutoSave = true,
MarkupCompatibilityProcessSettings = new MarkupCompatibilityProcessSettings(MarkupCompatibilityProcessMode.ProcessAllParts,
DocumentFormat.OpenXml.FileFormatVersions.Office2007),
MaxCharactersInPart = long.MaxValue
});
MainDocumentPart mainPart = doc.MainDocumentPart;
.
.Other stuff goes here
.
//now the fun...
Run r2 = new Run();
// Add an ImagePart.
ImagePart ip = mainPart.AddImagePart(ImagePartType.Png);
string imageRelationshipID = mainPart.CreateRelationshipToPart(ip); //
using (Stream imgStream = ip.GetStream())
{
System.Drawing.Bitmap b = new System.Drawing.Bitmap("myfile.png");
b.Save(imgStream, System.Drawing.Imaging.ImageFormat.Png);
}
Drawing drawing = BuildImage(imageRelationshipID, "name"+imageRelationshipID.ToString(), 17, 17);
r2.Append(drawing);
p.Append(r2);
The image part is essentially copied from http://blog.stuartwhiteford.com/?p=33) and is running in a loop presently. I also copied his BuildImage() function and use it as-is.
When I open the resulting docx, I see red Xs where the images are saying "This image cannot currently be displayed."
When I open the zip, the images will appear in root/media, but not root/word/media as I'd expect. I also cannot find the images referenced in any of the relationship files. Ideally they'd be in root/word/_rels/document.xml.rels. You'll notice I changed how imageRelationshipID is set hoping to fix this. It didn't.
Please help. Thank you.
So... It seems like OpenXML just hates me. I copied AddImagePart code from like 3-4 places among trying other things--none of which lasted long--and just could not get relationships to form. The implication I see is that they happen automatically with the AddImagePart function.
I ended up doing a complete workaround where I add all the pictures I might want to put and remove the Drawing nodes' parents of the ones I didn't want (Run nodes, generally.) Since these are very small pictures, it's feasible and in ways more elegant than trying to add them as necessary since I don't have to keep track of where images are stored on disk.

Watin Unit Tests with Nunit Timing problem

Hi i am using WatiN (version 2.0.10.928) with NUnit (2.5.2.9222)
if I have something like
[Test]
public void WebPageTest()
{
string url = "www.google.com";
IE ie = new IE(url);
ie.TextField(Find.ByTitle("Google Search")).TypeText("Watin");
ie.Button(Find.ByName("btnG")).Click();
ie.Element(Find.ByText("WatiN")).Click();
// ie.WaitForComplete();
Assert.IsTrue(ie.Text.Contains("Welcome at the WatiN"));
ie.Close();
}
Then usually this will work and the test will pass but sometimes when I hit the assert it seems that Watin hasn't finished loading the page and is still on the previous page. I have this problem using the IE.Text or the IE.Url properties. I tried using WaitForComplete() (even though that shouldn't be neccessary) but still sometimes have the same problem.
Has Anybody had this problem with WatiN before?
Has anybody succesufully managed to use WatiN with NUnit like this? Or Maybe it would work better with a different unit testing framework like MBUnit? Has anyone had better luck with MBunit?
The test framework you use will make no difference, I'm afraid -- this is one of the "gotchas" of any screen-scraping test framework, and WaTin is no different.
The WaitForComplete() call is definitely necessary, I'm afraid.
Some of my colleagues have reported that the version of IE can make a difference; IE6 in particular has some internal timing issues that can cause problems. IE8 appears to be quite a bit better.
I've had the same problem with my tests; unfortunately it doesn't seem as though you can assume that the WaitForComplete() that's supposed to be inherent in the Click() method will function correctly. Even explicitly calling WaitForComplete() afterward hasn't always worked.
As a last resort we have used System.Threading.Thread.Sleep(int timeout_in_milliseconds) to force the browser to give the page time to load. This isn't a completely bulletproof means of doing it, but it has eliminated about 90% of these sorts of errors. For the timeout we have used anything from 500 to 2000 milliseconds, depending on how long it takes to load and how quickly we want the test to run.
Try using
[Test]
public void WebPageTest()
{
string url = "www.google.com";
IE ie = new IE(url);
ie.TextField(Find.ByTitle("Google Search")).TypeText("Watin");
var btnG = ie.Button(Find.ByName("btnG"));
btnG.ClickNoWait();
ie.WaitForComplete(400);
var elementWatin = ie.Element(Find.ByText("WatiN"));
elementWatin.ClickNoWait();
ie.WaitForComplete(400);
Assert.IsTrue(ie.Text.Contains("Welcome at the WatiN"));
ie.Close();
}
Thanks
Gandhi Rajan
I have used ie.WaitForComplete() but it still does enforce waiting, and sometimes it times out, so I use
Settings.AttachToBrowserTimeOut = 200;
Settings.WaitForCompleteTimeOut = 200;
This worked for me.