Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #37574 > unrolled thread
| Started by | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| First post | 2017-10-17 08:47 -0700 |
| Last post | 2017-11-01 13:20 -0400 |
| Articles | 16 — 3 participants |
Back to article view | Back to comp.lang.java.programmer
How do you update the view space of a JTable? Eric Douglas <e.d.programmer@gmail.com> - 2017-10-17 08:47 -0700
Re: How do you update the view space of a JTable? Eric Douglas <e.d.programmer@gmail.com> - 2017-10-18 06:11 -0700
Re: How do you update the view space of a JTable? Daniele Futtorovic <da.futt.news@laposte.net> - 2017-10-30 17:41 +0100
Re: How do you update the view space of a JTable? Eric Douglas <e.d.programmer@gmail.com> - 2017-10-30 10:29 -0700
Re: How do you update the view space of a JTable? Daniele Futtorovic <da.futt.news@laposte.net> - 2017-10-31 11:10 +0100
Re: How do you update the view space of a JTable? Eric Douglas <e.d.programmer@gmail.com> - 2017-10-31 04:46 -0700
Re: How do you update the view space of a JTable? Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-10-31 07:59 -0400
Re: How do you update the view space of a JTable? Eric Douglas <e.d.programmer@gmail.com> - 2017-10-31 05:21 -0700
Re: How do you update the view space of a JTable? Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-10-31 08:32 -0400
Re: How do you update the view space of a JTable? Eric Douglas <e.d.programmer@gmail.com> - 2017-10-31 06:13 -0700
Re: How do you update the view space of a JTable? Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-10-31 17:13 -0400
Re: How do you update the view space of a JTable? Daniele Futtorovic <da.futt.news@laposte.net> - 2017-10-31 23:33 +0100
Re: How do you update the view space of a JTable? Eric Douglas <e.d.programmer@gmail.com> - 2017-11-01 06:29 -0700
Re: How do you update the view space of a JTable? Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-11-01 10:37 -0400
Re: How do you update the view space of a JTable? Eric Douglas <e.d.programmer@gmail.com> - 2017-11-01 08:37 -0700
Re: How do you update the view space of a JTable? Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-11-01 13:20 -0400
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2017-10-17 08:47 -0700 |
| Subject | How do you update the view space of a JTable? |
| Message-ID | <8a75cc49-c369-41bb-8e5e-254977d4e410@googlegroups.com> |
If I call setFillsViewportHeight(true) it doesn't paint the entire view space of the JScrollPane if the table doesn't have enough rows to fill it. I'm calling setFillsViewportHeight(false), and I'm overriding the BasicTableUI.paint() to do some custom cell drawing, but within this method the getClipBounds() of the Graphics is only returning the size of the rows. How do I increase this size? I've tried calling and overriding every method I can think of that should affect the size but it doesn't change. The only other thing I know of is to call setFillsViewportHeight(true) and have to clear any unused space.
[toc] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2017-10-18 06:11 -0700 |
| Message-ID | <63f3cd00-ae3d-4173-abc1-b403ca5af839@googlegroups.com> |
| In reply to | #37574 |
On Tuesday, October 17, 2017 at 11:47:18 AM UTC-4, Eric Douglas wrote:
> If I call setFillsViewportHeight(true) it doesn't paint the entire view space of the JScrollPane if the table doesn't have enough rows to fill it.
>
> I'm calling setFillsViewportHeight(false), and I'm overriding the BasicTableUI.paint() to do some custom cell drawing, but within this method the getClipBounds() of the Graphics is only returning the size of the rows. How do I increase this size? I've tried calling and overriding every method I can think of that should affect the size but it doesn't change. The only other thing I know of is to call setFillsViewportHeight(true) and have to clear any unused space.
So, I couldn't figure out how to call setFillsViewportHeight(false) and be able to draw anything in a JViewport outside of the space the table rows take up. The solution which seems to work is to call setFillsViewportHeight(true). This does not automatically clear the JViewport area outside of where the rows are drawn, and paints garbage in this space such as when I'm trying to drag a row. The fix to that is to override BasicTableUI and override the public void paint(Graphics g,JComponent c) to include this code.
Graphics2D g2d = (Graphics2D) g.create();
Composite saveMe = g2d.getComposite();
g2d.setComposite(AlphaComposite.Clear);
g2d.setBackground(c.getParent().getBackground());
g2d.clearRect(0, 0, c.getWidth(), c.getHeight());
g2d.setComposite(saveMe);
// call super.paint and/or manually paint table cells here
g2d.dispose();
[toc] | [prev] | [next] | [standalone]
| From | Daniele Futtorovic <da.futt.news@laposte.net> |
|---|---|
| Date | 2017-10-30 17:41 +0100 |
| Message-ID | <ot7kpq$koi$1@dont-email.me> |
| In reply to | #37574 |
On 2017-10-17 17:47, Eric Douglas wrote: > If I call setFillsViewportHeight(true) it doesn't paint the entire view space of the JScrollPane if the table doesn't have enough rows to fill it. > > I'm calling setFillsViewportHeight(false), and I'm overriding the BasicTableUI.paint() to do some custom cell drawing, but within this method the getClipBounds() of the Graphics is only returning the size of the rows. How do I increase this size? I've tried calling and overriding every method I can think of that should affect the size but it doesn't change. The only other thing I know of is to call setFillsViewportHeight(true) and have to clear any unused space. > Set a background for your scroll pane. Alternatively, you could mess with the TableModel to make it seem like there's more rows than you have data, but that's likely not the best idea. Mind rule #5008: if an established API like Swing repeatedly gets in the way of what you're trying to do, there's a good chance what you're trying to do is not a good idea. -- DF.
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2017-10-30 10:29 -0700 |
| Message-ID | <0a028d23-313f-4c8f-8516-80a5111e406a@googlegroups.com> |
| In reply to | #37609 |
On Monday, October 30, 2017 at 12:42:43 PM UTC-4, Daniele Futtorovic wrote: > > Set a background for your scroll pane. > > Alternatively, you could mess with the TableModel to make it seem like > there's more rows than you have data, but that's likely not the best idea. > > Mind rule #5008: if an established API like Swing repeatedly gets in the > way of what you're trying to do, there's a good chance what you're > trying to do is not a good idea. > > -- > DF. Not a good idea to do what a framework doesn't expect you to do? How would you ever be able to do anything new? I did find the way around this problem, though there's other problems because I'm making a dynamic JTable in a way apparently no one seems to have done before. See my other thread about frozen table rows. I'm trying to add a method to my JTable called setFrozenRows(int) to allow the user to scroll the table while leaving the first x rows in place. The only way I found to do this is by wrapping 2 tables into 1 scrollpane (JScrollPane contains a JPanel which contains 2 JScrollPanes which each contain a JTable). The API is not designed to do this, where I want to refer to them as 1 table. If I call setFrozenRows(2), rows 0-1 show in the top fixed table, and the bottom scrollable table starts with model row 2. Then if I call setSelectedRow(2) it should highlight the first row in the bottom table. I've been trying to do this with both tables sharing one table model, except clicking the first row of the second table still refers to it as row 0. A row filter didn't help with this. Run the example in the other thread and you'll see the row selection listener calling them row 0-1-0-1-2.. Either there is a better way to design that and I'm doing something wrong, or the design of the JTable classes is overly simplistic and needs to be hacked/overridden to handle it.
[toc] | [prev] | [next] | [standalone]
| From | Daniele Futtorovic <da.futt.news@laposte.net> |
|---|---|
| Date | 2017-10-31 11:10 +0100 |
| Message-ID | <ot9i92$7eg$1@dont-email.me> |
| In reply to | #37610 |
On 2017-10-30 18:29, Eric Douglas wrote: > On Monday, October 30, 2017 at 12:42:43 PM UTC-4, Daniele Futtorovic wrote: >> >> Set a background for your scroll pane. >> >> Alternatively, you could mess with the TableModel to make it seem like >> there's more rows than you have data, but that's likely not the best idea. >> >> Mind rule #5008: if an established API like Swing repeatedly gets in the >> way of what you're trying to do, there's a good chance what you're >> trying to do is not a good idea. > Not a good idea to do what a framework doesn't expect you to do? How would you ever be able to do anything new? > I did find the way around this problem, though there's other problems because I'm making a dynamic JTable in a way apparently no one seems to have done before. See my other thread about frozen table rows. > > I'm trying to add a method to my JTable called setFrozenRows(int) to allow the user to scroll the table while leaving the first x rows in place. > The only way I found to do this is by wrapping 2 tables into 1 scrollpane (JScrollPane contains a JPanel which contains 2 JScrollPanes which each contain a JTable). > The API is not designed to do this, where I want to refer to them as 1 table. If I call setFrozenRows(2), rows 0-1 show in the top fixed table, and the bottom scrollable table starts with model row 2. Then if I call setSelectedRow(2) it should highlight the first row in the bottom table. I've been trying to do this with both tables sharing one table model, except clicking the first row of the second table still refers to it as row 0. A row filter didn't help with this. Run the example in the other thread and you'll see the row selection listener calling them row 0-1-0-1-2.. > > Either there is a better way to design that and I'm doing something wrong, or the design of the JTable classes is overly simplistic and needs to be hacked/overridden to handle it. > Just sharing something I've learned over the years and issuing a humble recommendation. You say you've found a workaround, but it sounds like a lot of work and not much around to show for it. My empirically-based expectation is that it won't get much better until you reconsider your approach. From the sounds of it, what you're having is purely a visual, a presentation problem. There are many, many ways to present things, and it generally doesn't pay to brute-force one specific way of presenting when the framework doesn't seem to accommodate it. -- DF.
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2017-10-31 04:46 -0700 |
| Message-ID | <5037e6b0-3509-4ffd-a8f2-ad659c5b4d4b@googlegroups.com> |
| In reply to | #37618 |
On Tuesday, October 31, 2017 at 6:11:53 AM UTC-4, Daniele Futtorovic wrote: > Just sharing something I've learned over the years and issuing a humble > recommendation. You say you've found a workaround, but it sounds like a > lot of work and not much around to show for it. My empirically-based > expectation is that it won't get much better until you reconsider your > approach. From the sounds of it, what you're having is purely a visual, > a presentation problem. There are many, many ways to present things, and > it generally doesn't pay to brute-force one specific way of presenting > when the framework doesn't seem to accommodate it. > > -- > DF. Did you see the other message with the link to the runnable sample? Are you here to help with that or just to criticize?
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2017-10-31 07:59 -0400 |
| Message-ID | <ot9ois$idb$1@dont-email.me> |
| In reply to | #37619 |
On 10/31/2017 7:46 AM, Eric Douglas wrote:
> On Tuesday, October 31, 2017 at 6:11:53 AM UTC-4, Daniele Futtorovic wrote:
>> Just sharing something I've learned over the years and issuing a humble
>> recommendation. You say you've found a workaround, but it sounds like a
>> lot of work and not much around to show for it. My empirically-based
>> expectation is that it won't get much better until you reconsider your
>> approach. From the sounds of it, what you're having is purely a visual,
>> a presentation problem. There are many, many ways to present things, and
>> it generally doesn't pay to brute-force one specific way of presenting
>> when the framework doesn't seem to accommodate it.
>>
>> --
>> DF.
>
> Did you see the other message with the link to the runnable sample?
No, neither on eternal-september nor in Google Groups. Was it
posted in some other thread? Some other newsgroup? Some other life?
FWIW, Daniele is not the only person to observe that you seem to
be fighting Swing rather than using it. If it is so antithetical to
your desired way of doing things, why bother with it at all?
--
esosman@comcast-dot-net.invalid
Eleven hundred seventy-seven days to go.
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2017-10-31 05:21 -0700 |
| Message-ID | <66fc1800-d494-43a1-963d-a1a54a99f631@googlegroups.com> |
| In reply to | #37620 |
On Tuesday, October 31, 2017 at 7:59:33 AM UTC-4, Eric Sosman wrote: > No, neither on eternal-september nor in Google Groups. Was it > posted in some other thread? Some other newsgroup? Some other life? > > FWIW, Daniele is not the only person to observe that you seem to > be fighting Swing rather than using it. If it is so antithetical to > your desired way of doing things, why bother with it at all? > You also missed the message I posted just yesterday? https://pastebin.com/zrUESqc4
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2017-10-31 08:32 -0400 |
| Message-ID | <ot9qht$3bf$1@dont-email.me> |
| In reply to | #37621 |
On 10/31/2017 8:21 AM, Eric Douglas wrote:
> On Tuesday, October 31, 2017 at 7:59:33 AM UTC-4, Eric Sosman wrote:
>> No, neither on eternal-september nor in Google Groups. Was it
>> posted in some other thread? Some other newsgroup? Some other life?
>>
>> FWIW, Daniele is not the only person to observe that you seem to
>> be fighting Swing rather than using it. If it is so antithetical to
>> your desired way of doing things, why bother with it at all?
>>
>
> You also missed the message I posted just yesterday?
>
> https://pastebin.com/zrUESqc4
Ah, yes, how silly of me: I should have looked in a completely
different thread to find your link. Pray accept my apologies for
being so lax.
--
esosman@comcast-dot-net.invalid
Eleven hundred seventy-seven days to go.
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2017-10-31 06:13 -0700 |
| Message-ID | <28c95541-33f4-4502-af4e-31d82c672841@googlegroups.com> |
| In reply to | #37622 |
On Tuesday, October 31, 2017 at 8:33:09 AM UTC-4, Eric Sosman wrote: > > > > https://pastebin.com/zrUESqc4 > > Ah, yes, how silly of me: I should have looked in a completely > different thread to find your link. Pray accept my apologies for > being so lax. > That is what I said, check the other thread, so far no one responded there. I can move that conversation here if it'll help.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2017-10-31 17:13 -0400 |
| Message-ID | <otap2d$uss$1@dont-email.me> |
| In reply to | #37623 |
On 10/31/2017 9:13 AM, Eric Douglas wrote:
> On Tuesday, October 31, 2017 at 8:33:09 AM UTC-4, Eric Sosman wrote:
>>>
>>> https://pastebin.com/zrUESqc4
>>
>> Ah, yes, how silly of me: I should have looked in a completely
>> different thread to find your link. Pray accept my apologies for
>> being so lax.
>>
>
> That is what I said, check the other thread, so far no one responded there. I can move that conversation here if it'll help.
A brief look at the code reveals one serious error (of the
kind you'll "usually" get away with), one serious error that no
Java programmer should ever commit, a few venial sins, and some
opportunities for stylistic improvement. What it doesn't reveal
is the code's purpose nor how it fails to fulfill that purpose,
which makes it a little hard to diagnose ...
Herewith, the problems apparent to my brief inspection:
- Serious: Swing is not thread-safe, and almost all
Swingstuff must be done on the event dispatching thread (EDT).
Your code constructs and launches a JFrame and all its contents from
whatever thread executes main(). You'll "usually" get away with this,
because Murphy waits until the Big Demo for the Big Boss. See
https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html
- Serious: `catch (Exception e)'? Are you KIDDING?
- Venial: Various constructors call potentially overridable
methods, which could be a problem if any of your classes are someday
extended. You could cure this by making the involved classes final,
or by making the methods final, or (since you probably don't need to
override some of them) by explicitly calling the superclass' method,
as in `super.getContentPane()' instead of just `getContentPane()'.
Or, you could just hope no one will ever extend the class and find
some reason to override setAutoResizeMode() or whatever.
- Venial: Various constructors leak the `this' reference before
`this' is fully constructed. The transgression would ordinarily be
worse than venial, but adding event listeners "should probably be"
safe since they're unlikely to be called until a good deal later.
IMHO this is an infelicity in the architecture of Swing/AWT: You
would *like* a constructor to deliver a fully-functional ready-to-
rumble instance of a JFrame or whatever, but if you're really not
supposed to register event listeners in a constructor ... The
squeaky-clean approach, I guess, is to have a post-construction
init() method, which strikes me as Ugly. Or ignore it and hope.
- Venial: The `MyTable' class is package-private, yet some
`public' methods either return it or use it as a parameter. Either
make the class `public' or make the methods package-private: Pay
attention to your access levels.
- Style: Sleekness could be improved with a lambda expression
instead of an anonymous inner subclass of AdjustmentListener.
- Style: Use `intValue' instead of `new Integer(intValue)' and
let auto-boxing take care of wrapping it. (May produce a tiny gain
in efficiency, too.)
- Style: Instead of calling System.exit() on a window-close event,
you could just `setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)'.
- Style: The types of some fields are unnecessarily specific:
`AbstractTableModel' instead of `TableModel', that sort of thing.
It is usually "better form" to use the least specific declaration
that's suitable -- often, an interface rather than a particular
implementation of that interface. That way, you retain flexibility
to change the implementation later with little or no upheaval.
I sincerely doubt that fixing any of the above will help you
in the least with whatever problem you're having in the pursuit of
whatever goal you're after, but "Cleanliness is next to Godliness,
also next to impossible."
--
esosman@comcast-dot-net.invalid
Eleven hundred seventy-seven days to go.
[toc] | [prev] | [next] | [standalone]
| From | Daniele Futtorovic <da.futt.news@laposte.net> |
|---|---|
| Date | 2017-10-31 23:33 +0100 |
| Message-ID | <otatqv$4l5$1@dont-email.me> |
| In reply to | #37632 |
On 2017-10-31 22:13, Eric Sosman wrote: > - Venial: Various constructors leak the `this' reference before > `this' is fully constructed. The transgression would ordinarily be > worse than venial, but adding event listeners "should probably be" > safe since they're unlikely to be called until a good deal later. > IMHO this is an infelicity in the architecture of Swing/AWT: You > would *like* a constructor to deliver a fully-functional ready-to- > rumble instance of a JFrame or whatever, but if you're really not > supposed to register event listeners in a constructor ... Very much seconded. I don't do much Swing any more these days, but what I used to do when I did, was to move a lot of initialisation and registration to the Component#addNotify (and the cleanup in Component#removeNotify) method. It seemed to work fairly well. -- DF.
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2017-11-01 06:29 -0700 |
| Message-ID | <fd194d27-8172-4ba2-b90e-44843e950cf8@googlegroups.com> |
| In reply to | #37632 |
Apologies for much of the style issues, a fair amount of this example was copy-pasted from somewhere on the internet, not exactly how I would write. I just modified it enough to demonstrate what functionality I need.
On Tuesday, October 31, 2017 at 5:13:57 PM UTC-4, Eric Sosman wrote:
> A brief look at the code reveals one serious error (of the
> kind you'll "usually" get away with), one serious error that no
> Java programmer should ever commit, a few venial sins, and some
> opportunities for stylistic improvement. What it doesn't reveal
> is the code's purpose nor how it fails to fulfill that purpose,
> which makes it a little hard to diagnose ...
>
> Herewith, the problems apparent to my brief inspection:
>
> - Serious: Swing is not thread-safe, and almost all
> Swingstuff must be done on the event dispatching thread (EDT).
> Your code constructs and launches a JFrame and all its contents from
> whatever thread executes main(). You'll "usually" get away with this,
> because Murphy waits until the Big Demo for the Big Boss. See
> https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html
>
Easy enough. I don't normally do that. Adjusting that main procedure to look like my other tests would at least do this:
public static void main(final String[] args) {
EventQueue.invokeLater(() -> {
showGui();
});
}
protected static void showGui() {
final FixedRowExample frame = new FixedRowExample();
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(final WindowEvent e) {
System.exit(0);
}
});
frame.pack();
frame.setVisible(true);
}
(while some of my more complex tests involve a SwingWorker)
> - Serious: `catch (Exception e)'? Are you KIDDING?
>
I'm not sure what exception(s) that was expecting to catch. More specifically it only appears to need:
} catch (UnsupportedFlavorException | IOException e) {
> - Venial: Various constructors call potentially overridable
> methods, which could be a problem if any of your classes are someday
> extended. You could cure this by making the involved classes final,
> or by making the methods final, or (since you probably don't need to
> override some of them) by explicitly calling the superclass' method,
> as in `super.getContentPane()' instead of just `getContentPane()'.
> Or, you could just hope no one will ever extend the class and find
> some reason to override setAutoResizeMode() or whatever.
>
I'm not sure exactly where or why this is bad form? Obviously the getContentPant() is from Oracle's JFrame which is overridable, and I've found many Oracle classes and methods can be overridden including ones which probably should not be. Of course this is just a test class so it doesn't hurt for this class and it's subclasses to be final. Many if not most test classes on the internet seem to extend JFrame, though I've tried not to do that in my own tests, so rather than super.getContentPane() it should really be testFrame1.getContentPane(). I haven't used final on any classes or methods personally since I haven't seen confirmation of it improving performance and I'm not sure when you really need to ensure that no one overrides a method which must be visible.
> - Venial: Various constructors leak the `this' reference before
> `this' is fully constructed. The transgression would ordinarily be
> worse than venial, but adding event listeners "should probably be"
> safe since they're unlikely to be called until a good deal later.
> IMHO this is an infelicity in the architecture of Swing/AWT: You
> would *like* a constructor to deliver a fully-functional ready-to-
> rumble instance of a JFrame or whatever, but if you're really not
> supposed to register event listeners in a constructor ... The
> squeaky-clean approach, I guess, is to have a post-construction
> init() method, which strikes me as Ugly. Or ignore it and hope.
>
I'm not sure where exactly you're referring to this or how exactly it could be improved. Am I just not understanding or do you not like how Oracle does GUI? ie JTable.setModel references this and is called from the constructor.
> - Venial: The `MyTable' class is package-private, yet some
> `public' methods either return it or use it as a parameter. Either
> make the class `public' or make the methods package-private: Pay
> attention to your access levels.
>
A non-issue I simply hadn't noticed due to this being a self contained test class, not a problem making that public as it should be in an API.
> - Style: Sleekness could be improved with a lambda expression
> instead of an anonymous inner subclass of AdjustmentListener.
>
I would like to see syntax that improves that. I haven't worked with a lot of lambdas myself, only implementing them in a couple of places where I couldn't see any other way to code, or where I found a shortcut which doesn't take away from readability as in the previously mentioned EventQueue.invokeLater.
> - Style: Use `intValue' instead of `new Integer(intValue)' and
> let auto-boxing take care of wrapping it. (May produce a tiny gain
> in efficiency, too.)
>
That actually may be required for an older version of Java? I just took that out altogether and the compiler just accepted the method's int return value for the constructor's Object parameter. It seems the only reason anymore to explicitly convert ie int to Integer is if you need to call a method, though most Integer methods can be done with static calls.
> - Style: Instead of calling System.exit() on a window-close event,
> you could just `setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)'.
>
I don't recall if I wrote that part or copied it. This is another thing which is obviously only done because it's a self contained test. I normally use the window listener method, but I normally don't exit the application when it closes. Our standard window close does the "are you sure?" popup.
> - Style: The types of some fields are unnecessarily specific:
> `AbstractTableModel' instead of `TableModel', that sort of thing.
> It is usually "better form" to use the least specific declaration
> that's suitable -- often, an interface rather than a particular
> implementation of that interface. That way, you retain flexibility
> to change the implementation later with little or no upheaval.
>
Just referring to declarations, nor construction? ie
final AbstractTableModel fixedModel = new AbstractTableModel() {
could be
final TableModel fixedModel = new AbstractTableModel() {
I'm not aware of any good table models which don't extend AbstractTableModel, but if it's possible for this table to work properly without extending it that would be fine.
> I sincerely doubt that fixing any of the above will help you
> in the least with whatever problem you're having in the pursuit of
> whatever goal you're after, but "Cleanliness is next to Godliness,
> also next to impossible."
>
Agreed, none of this helps toward the goal of having one JTable with a set number of fixed rows followed by a variable number of scrollable rows having methods like setSelectedRow() refer to all the rows as part of a single table (though the solution appears to require the fixed and scrollable regions in separate tables), but any advice which improves coding practice is always welcome.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2017-11-01 10:37 -0400 |
| Message-ID | <otcm6d$q0u$1@dont-email.me> |
| In reply to | #37634 |
On 11/1/2017 9:29 AM, Eric Douglas wrote:
> On Tuesday, October 31, 2017 at 5:13:57 PM UTC-4, Eric Sosman wrote:
>> [...]
>> - Venial: Various constructors call potentially overridable
>> methods, which could be a problem if any of your classes are someday
>> extended. You could cure this by making the involved classes final,
>> or by making the methods final, or (since you probably don't need to
>> override some of them) by explicitly calling the superclass' method,
>> as in `super.getContentPane()' instead of just `getContentPane()'.
>> Or, you could just hope no one will ever extend the class and find
>> some reason to override setAutoResizeMode() or whatever.
>>
> I'm not sure exactly where or why this is bad form? Obviously the getContentPant() is from Oracle's JFrame which is overridable, and I've found many Oracle classes and methods can be overridden including ones which probably should not be. Of course this is just a test class so it doesn't hurt for this class and it's subclasses to be final. Many if not most test classes on the internet seem to extend JFrame, though I've tried not to do that in my own tests, so rather than super.getContentPane() it should really be testFrame1.getContentPane(). I haven't used final on any classes or methods personally since I haven't seen confirmation of it improving performance and I'm not sure when you really need to ensure that no one overrides a method which must be visible.
The "bad form" in calling an overridable method from a constructor
is, well, that the method might be overridden. Specifically, it might
be overridden in a subclass, in which case you'd wind up calling an
instance method of an object that is not yet fully constructed. This
could lead to unpleasant surprises, like observing a `final' field to
have different values at different times, or getting NPE when the
subclass' overriding method does something "safe" like
class Super {
Super() {
// ...
theMethod();
}
void theMethod() {
// ...
}
}
class Sub extends Super {
private final List<String> names = new ArrayList<>();
@Override
void theMethod() {
names.add("Clark Kent");
}
}
So: The rule for avoiding such nastiness is to call no overridable
methods from a constructor. Three ways to accomplish this (there may
be others) are
- Make the class `final' and don't override the method. Since no
one can extend the `final' class, no one can override the method.
- Override the method, but make your override `final'. The class
can now be extended, but no one can override the method.
- Call `super.theMethod()' explicitly. Even if a subclass overrides
the method, the call will still go to super's implementation.
I can't find "testFrame1" in your code, so I don't know what your
reference to it means.
>> - Venial: Various constructors leak the `this' reference before
>> `this' is fully constructed. The transgression would ordinarily be
>> worse than venial, but adding event listeners "should probably be"
>> safe since they're unlikely to be called until a good deal later.
>> IMHO this is an infelicity in the architecture of Swing/AWT: You
>> would *like* a constructor to deliver a fully-functional ready-to-
>> rumble instance of a JFrame or whatever, but if you're really not
>> supposed to register event listeners in a constructor ... The
>> squeaky-clean approach, I guess, is to have a post-construction
>> init() method, which strikes me as Ugly. Or ignore it and hope.
>>
> I'm not sure where exactly you're referring to this or how exactly it could be improved. Am I just not understanding or do you not like how Oracle does GUI? ie JTable.setModel references this and is called from the constructor.
It is dangerous to expose a reference to an object that is not yet
fully built. An object is not fully built until its entire chain of
constructors has completed. Something like `addActionListener(this)'
publishes an object reference to code in another class, and if done
in a constructor it is obviously done before the constructor chain
has finished. The exposed object is incomplete, there are (at least
potentially) threading problems with memory visibility and so on, and
the program is in peril.
As I said, you will "probably" be all right with this one (in this
case), because events won't begin to fire for a while yet and there's
"no good reason" for an event source to do anything with your object
until they do. Daniele Futtorovic's dodge of registering listeners in
addNotify() is an approach that hadn't occurred to me; seems clever.
>> - Style: Use `intValue' instead of `new Integer(intValue)' and
>> let auto-boxing take care of wrapping it. (May produce a tiny gain
>> in efficiency, too.)
>>
> That actually may be required for an older version of Java? I just took that out altogether and the compiler just accepted the method's int return value for the constructor's Object parameter. It seems the only reason anymore to explicitly convert ie int to Integer is if you need to call a method, though most Integer methods can be done with static calls.
You're right: Auto-boxing requires a Java 1.5 or later. If you must
accommodate Java 1.4, you can't auto-box. (Notes: 1.5 came out thirteen
years ago, 1.4 went off public support nine years ago, and 1.4 went off
pay-Oracle-for-special-treatment-support four and a half years ago.)
I have no idea what you mean by "static calls," nor why they might
be relevant to auto-boxing.
--
esosman@comcast-dot-net.invalid
Eleven hundred seventy-six days to go.
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2017-11-01 08:37 -0700 |
| Message-ID | <dc0a0a65-6ab1-455b-a2cd-c05b35176ce6@googlegroups.com> |
| In reply to | #37635 |
On Wednesday, November 1, 2017 at 10:37:10 AM UTC-4, Eric Sosman wrote:
> I can't find "testFrame1" in your code, so I don't know what your
> reference to it means.
That is to say instead of doing
public final class FixedRowExample extends JFrame {
super("Fixed Row Example");
to use a separate object
public FixedRowExample() {
JFrame testFrame1 = new JFrame("Fixed Row Example");
Then to use testFrame1 for the calls to getContentPane(), addWindowListener(), pack(), and setVisible().
> It is dangerous to expose a reference to an object that is not yet
> fully built. An object is not fully built until its entire chain of
> constructors has completed. Something like `addActionListener(this)'
> publishes an object reference to code in another class, and if done
> in a constructor it is obviously done before the constructor chain
> has finished. The exposed object is incomplete, there are (at least
> potentially) threading problems with memory visibility and so on, and
> the program is in peril.
>
Isn't that what Oracle does, like where JTable constructor calls setModel() which calls dataModel.addTableModelListener(this)? (and the same for their row and column selection listeners) If that's not what you're talking about then I'm not sure what you're saying should be changed and how.
> As I said, you will "probably" be all right with this one (in this
> case), because events won't begin to fire for a while yet and there's
> "no good reason" for an event source to do anything with your object
> until they do. Daniele Futtorovic's dodge of registering listeners in
> addNotify() is an approach that hadn't occurred to me; seems clever.
>
A separate method to register external listeners always makes sense, but requiring everyone who creates an instance of your GUI object to call a separate method right after the constructor to register it's own internal listeners for basic functionality?
> You're right: Auto-boxing requires a Java 1.5 or later. If you must
> accommodate Java 1.4, you can't auto-box. (Notes: 1.5 came out thirteen
> years ago, 1.4 went off public support nine years ago, and 1.4 went off
> pay-Oracle-for-special-treatment-support four and a half years ago.)
>
I'd have to see where it came from but it's quite possible code copied from the internet is more than 10 years old.
> I have no idea what you mean by "static calls," nor why they might
> be relevant to auto-boxing.
>
int iVal = 1;
then either
String sVal = new Integer(iVal).toString();
or
String sVal = ((Integer)iVal).toString();
versus
String sVal = String.valueOf(iVal);
Most if not all the methods of these classes (Integer, Double, etc) can also be done statically.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2017-11-01 13:20 -0400 |
| Message-ID | <otcvoe$7s9$1@dont-email.me> |
| In reply to | #37636 |
On 11/1/2017 11:37 AM, Eric Douglas wrote:
> [...]
> int iVal = 1;
> then either
> String sVal = new Integer(iVal).toString();
> or
> String sVal = ((Integer)iVal).toString();
Huh?
> versus
> String sVal = String.valueOf(iVal);
or
String sVal = Integer.toString(iVal);
--
esosman@comcast-dot-net.invalid
Eleven hundred seventy-six days to go.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web