Solved

TableLayout issues

Posted on 2003-12-01
28
498 Views
Last Modified: 2010-03-31
I have a class that is a container for displaying an image.  What I am trying to do is to create multiple contiainers and adding them to a TableLayout object so I have a table of images.  Right now it is working, for the most part, but there are two issues I am facing.

1) I cannot seem to get the images centered.  The entire layout appears to be right aligned - I haven't looked into this too much yet, but hopefully there is an easy solution to that.

2) My biggest problem is an error that is being generated when repainting all my my container objects that display my images.  Here is there error:

Exception occurred during event dispatching:
java.lang.NullPointerException
      at sun.java2d.SunGraphics2D.drawImage(SunGraphics2D.java:2765)
      at sun.java2d.SunGraphics2D.drawImage(SunGraphics2D.java:2726)
      at ImageContainer.paintComponent(ImageContainer.java:107)
      at javax.swing.JComponent.paint(JComponent.java:808)
      at javax.swing.JComponent.paintChildren(JComponent.java:647)
      at javax.swing.JComponent.paint(JComponent.java:817)
      at javax.swing.JComponent.paintWithOffscreenBuffer(JComponent.java:4771)
      at javax.swing.JComponent.paintDoubleBuffered(JComponent.java:4724)
      at javax.swing.JComponent._paintImmediately(JComponent.java:4668)
      at javax.swing.JComponent.paintImmediately(JComponent.java:4477)
      at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:410)
      at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:117)
      at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:178)
      at java.awt.EventQueue.dispatchEvent(EventQueue.java:448)
      at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:197)
      at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
      at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:140)
      at java.awt.Dialog.show(Dialog.java:551)
      at RawImage.doLoadFile(RawImage.java:249)
      at RawImageMenuBar.actionPerformed(RawImageMenuBar.java:127)
      at java.awt.MenuItem.processActionEvent(MenuItem.java:588)
      at java.awt.MenuItem.processEvent(MenuItem.java:548)
      at java.awt.MenuComponent.dispatchEventImpl(MenuComponent.java:285)
      at java.awt.MenuComponent.dispatchEvent(MenuComponent.java:273)
      at java.awt.EventQueue.dispatchEvent(EventQueue.java:452)
      at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:197)
      at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:144)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:136)
      at java.awt.EventDispatchThread.run(EventDispatchThread.java:99)

I don't quite see what is going on there - I did something to change the layout and the error went away, but I couldn't do much with how that layout was setup (I think I just had it directly on the frame...whereas now I have it on a panel that is added to the frame).

Here is some code extracts of how I am getting this to work:


        // create table layout for the frame
        layout = new TableLayout();

        panel = new JPanel();
        panel.setPreferredSize( new Dimension( 500, 500 ) );
        panel.setLayout( layout );
.
.
.
       // later on when I am loading the images
       int numRows = ( stacks.size() / 5 ) + 1;
       if ( ( stacks.size() % 5 ) > 0 )
           numRows++;

       double [] rows = new double[ numRows ];
       double [] cols = new double[ 6 ];

        // set columns
        for ( int i=0; i<cols.length; i++ ) {
            cols[ i ] = 175;
                                }

        // set rows
        for ( int i=0; i<rows.length; i++ ) {
            rows[ i ] = 175;
        }

        // layout.setConstraints( panel, tlc );
        layout.setVGap( 2 );
        layout.setHGap( 2 );
        layout.setColumn( cols );
        layout.setRow( rows );

        panel.setLayout( layout );

        // then in a for loop I create container objects of the images being loaded and add them to the panel
        int currRow = ( i / 5 ) + 1;
        int currCol = ( i % 5 ) + 1;

        panel.add( container, String.valueOf( currCol ) + ", " + String.valueOf( currRow ) + ", f, c" );


        // after the for loop I finish up with the panel
        panel.doLayout();
        panel.repaint();

Thanks for any help!
0
Comment
Question by:ctjoumas
  • 15
  • 8
  • 5
28 Comments
 
LVL 35

Expert Comment

by:girionis
Comment Utility
 Which is the line that throws the null pointer exception?
0
 

Author Comment

by:ctjoumas
Comment Utility
Well, it is kinda strange.  It is in my image container class (which is what I am displaying multiple instances of in my table layout):

    public void paintComponent( Graphics g ) {
        g.drawImage( displayImage, 0, 0, getWidth(), getHeight(), this );
    } // end paintComponent


I'm not sure how the drawImage line is throwing the null pointer exception though..  But, it is usually the first image that isn't fully painted - but I have a component listener in that contianer class and when it resizes, it will callt he same paint component (for all image containers that are in my layout of course) and I never see the error again.
0
 
LVL 35

Expert Comment

by:girionis
Comment Utility
 So does it only happens with the first image? Do the rest work fine?
0
 

Author Comment

by:ctjoumas
Comment Utility
Well, I am not sure if it happens with the first one or not - in each container, I have an image number so I printed that out before the drawImage - and the only number printed before painting is 7...  but this seems to change.  It appears to be random as to which image number is causing hte problem - but that is the only time the painting causes an error...any time the images are repainted, no error occurs.
0
 
LVL 35

Expert Comment

by:girionis
Comment Utility
 Not sure what's going on and I cannot infer anything from the code.

  What did you do here

> I don't quite see what is going on there - I did something to change the layout and the error went away

  and the error went away?
0
 

Author Comment

by:ctjoumas
Comment Utility
What I did was just create a popup frame to hold the table layout of images....that works fine.  But, the layout is still weird - it appears centered when it is maximized.  Regardless, I can't have a popup for it - i need to get these to load and appear centered on a panel that will be in my main window frame.

I'm not sure what else to post to show what is going wrong - what I have posted is the main process of how everything is being constructed.  I am also stumped as to what is going on with the error when the images are painted for the first time.
0
 
LVL 92

Expert Comment

by:objects
Comment Utility
the error looks like it is caused by trying to paint a null image.
0
 

Author Comment

by:ctjoumas
Comment Utility
That's what it looks like, but I don't see how that can happen.  Here is hte basic logic that goes on for setting my container objects, which is what I am adding to the TableLayout - and these are nothing more than a panel used to display an image from the stack of images:

1) read in all image stacks and store them (ImagePlus objects) in a Vector.
2) loop through all stacks in the vector
  - create a new container object and set the image to the first image from the current ImagePlus stack
  - add the container to the next free cell in hte TableLayout
3) the loop has finished, so now let's repaint the panel that has its layout set to the TableLayout.

So, all images in my container object should be valid and not null.
0
 
LVL 92

Expert Comment

by:objects
Comment Utility
print out the value of displayImage in paintComponent() to check.
0
 
LVL 35

Expert Comment

by:girionis
Comment Utility
 Can you post a small compilable example that demonstrates the problem?
0
 

Author Comment

by:ctjoumas
Comment Utility
The value of displayImage is null when it generates the error - but I don't see why this would be the case.  displayImage is set each time my container is created - but I must be looking over something.  I'll be looking back into it.  But, I think the other important problem is the alignment issues.

When my program is loaded up, it is set to dimensions of 500x500 and when the images are loaded and layed out in the TableLayout, they seem to be right aligned.

I will look into this problem a little bit, and if it doesn't work I will try and post some code that will simplify my problem.

Chris
0
 

Author Comment

by:ctjoumas
Comment Utility
Ok, I tried to shorten up the code and only include just the loading and displaying of the images.  This is a very crude mockup of the project - but it shows the error I am getting and should be relatively short.  Hope this helps - there are three classes/files:

Main Class:
--------------------------------------------------------------------------
import ij.ImagePlus;
import info.clearthought.layout.TableLayout;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.Vector;

public class RawImage extends Frame {

    // TESTING TABLELAYOUT
    private TableLayout layout;
    private JPanel panel;
    private Vector containers = new Vector();

    /**
     * Container object for the image being loaded.
     */
    private ImageContainer container = null;

    /**
     * A vector of images
     */
    private Vector images = new Vector();

    /**
     * Main function.  Creates an object of itself and displays it
     * on the screen.
     * @param args Command line argument array
     */
    public static void main( String [] args ) {

        RawImage ri = new RawImage();

        ri.pack();

        // center on screen
        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
        Rectangle abounds = ri.getBounds();
        ri.setLocation( ( dim.width - abounds.width ) / 2, ( dim.height - abounds.height ) / 2 );

        ri.show();

    } // end main

    /**
     * Constructor.  Builds the GUI for the program.
     */
    public RawImage() {

        super( "Raw Image Loader" );

        // Allow user to close the window to terminate the program
        addWindowListener(new WindowAdapter() {
            public void windowClosing (WindowEvent e) {
                System.exit( 0 );
            }
        } );

        setLayout( new BoxLayout( this, BoxLayout.Y_AXIS ) );
        setBackground( Color.lightGray );

        // create table layout for the frame
        layout = new TableLayout();

        panel = new JPanel();
        panel.setPreferredSize( new Dimension( 500, 500 ) );
        panel.setLayout( layout );

        // get menu bar from RawImageMenuBar class
        setMenuBar( new RawImageMenuBar( this ) );

        add( panel );

    } // end constructor

    /**
     * Loads the file containing the raw pixel data of multiple slices, which
     * may or may not make up a movie, and uses a thread to read in the file
     * and create multiple stacks from it.
     */
    public void doLoadFile() {

        File [] f = null;

        JFileChooser chooser = new JFileChooser( "P:/" );
        chooser.setMultiSelectionEnabled( true );
        chooser.setDialogTitle( "Load Images" );

        int returnVal = chooser.showOpenDialog( this );

        if ( returnVal == JFileChooser.APPROVE_OPTION ) {
            f = chooser.getSelectedFiles();
        }

        final File [] files = f;

        if ( files.length > 0 ) {

            try {

                ImagePlus ip = null;

                // clear the stacks vector from any previously loaded stacks
                images.clear();

                for ( int i=0; i<files.length; i++ ) {

                    ip = new ImagePlus( files[ i ].getAbsolutePath() );

                    images.add( ip.getImage() );

                } // end for

                int numRows = ( images.size() / 5 ) + 1;
                if ( ( images.size() % 5 ) > 0 )
                    numRows++;

                double [] rows = new double[ numRows ];
                double [] cols = new double[ 6 ];

                // set columns
                for ( int i=0; i<cols.length; i++ ) {
                    cols[ i ] = 175;
                }

                // set rows
                for ( int i=0; i<rows.length; i++ ) {
                    rows[ i ] = 175;
                }

                // layout.setConstraints( panel, tlc );
                layout.setVGap( 2 );
                layout.setHGap( 2 );
                layout.setColumn( cols );
                layout.setRow( rows );

                panel.setLayout( layout );

                for ( int i=0; i<images.size(); i++ ) {

                    container = new ImageContainer();

                    // set the imageplus object to the first stack
                    displayImage( i );

                    int currRow = ( i / 5 ) + 1;
                    int currCol = ( i % 5 ) + 1;

                    panel.add( container, String.valueOf( currCol ) + ", " + String.valueOf( currRow ) + ", f, c" );

                    // add the image container object to the vector of image containers
                    containers.add( container );

                }

                panel.doLayout();
                panel.repaint();

            } catch ( Exception e ) {
                e.printStackTrace();
            } // end try - catch

        } // end if

    } // end doLoadFile

    /**
     * Displays an image in the ImagePlus stack in the image container.
     *
     * @param imageNumber the image number being displayed
     */
    public void displayImage( int imageNumber ) {

        Image i = (Image) images.get( imageNumber );
        container.setImage( i );

    } // end displayImage

} // end class
--------------------------------------------------------------------------

MenuBar Class:
--------------------------------------------------------------------------
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class RawImageMenuBar extends MenuBar implements ActionListener {

    /**
     * Handle to the parent application
     */
    private RawImage rawImageObj = null;

    /**
     * Handle to the File - Exit option for event handling purposes
     */
    private MenuItem exit = null;

    /**
     * Handle to the File - Open File option for event handling purposes
     */
    private MenuItem openFiles = null;

    /**
     * Constructor.
     *
     * @param ri the parent object
     */
    public RawImageMenuBar( RawImage ri ) {

        rawImageObj = ri;

        // Create File Menu
        Menu menuFile = new Menu( "File" );

        openFiles = new MenuItem( "Open Files" );
        menuFile.add( openFiles );
        openFiles.addActionListener( this );

        menuFile.addSeparator();

        exit = new MenuItem( "Exit" );
        menuFile.add( exit );
        exit.addActionListener( this );

        // add menus to main menu bar
        add( menuFile );

    } // end constructor

    /**
     * Event handler/delegate function.
     *
     * @param e Event information object
     */
    public void actionPerformed( ActionEvent e ) {

        Object src = e.getSource();

        if ( src.equals( exit ) ) {
            System.exit( 0 );
        } else if ( src.equals( openFiles ) ) {
            rawImageObj.doLoadFile();
        } // end if - else

    } // end actionPerformed

} // end class
--------------------------------------------------------------------------

ImageContainer Class:
--------------------------------------------------------------------------
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.event.*;

/**
 * <strong>ImageContainer</strong> - Component that holds an image object created
 * from raw pixel data.  When no image is loaded, this component will display a
 * white background with a "no image message" complaint that will be clickable in
 * order to popup a chooser for loading a file.
 *
 * @author Chris Tjoumas
 */
public class ImageContainer extends JPanel implements ComponentListener {

    /**
       * ActionListener object to activate when the component is clicked on and the component is in an invalid state
       */
      private ActionListener invalidAction;

    /**
     * Image that was loaded.
     */
    private Image image;

    /**
       * Off-screen buffer for drawing things before they are displayed. Especially usefull for its Graphics2D capabilities.
       */
      private BufferedImage displayImage;

    /**
       * Graphics context for drawing stuff off-screen
       */
      private Graphics2D display;

    /**
     * Creates a container to display the loaded image.
     */
    public ImageContainer() {

        setPreferredSize( new Dimension( 250, 250 ) );

        setOpaque( true );

        addComponentListener( this );

    } // end constructor

    /**
     * Paint the body of the component.
     *
     * @param g Graphics context on which to draw.
     */
    public void paintComponent( Graphics g ) {
        g.drawImage( displayImage, 0, 0, getWidth(), getHeight(), this );
    } // end paintComponent

       /**
       * Mutator for what to do on a mouse click in an invalid state (not having an image loaded yet).
       */
      public void setInvalidAction( ActionListener a ) {
            invalidAction = a;
      } // end setInvalidAction

    /**
       * Unused mouse callback.
       *
       * @param e Event information object.
       */
      public void mouseClicked( MouseEvent e ) { }

      /**
       * Unused mouse callback.
       *
       * @param e Event information object.
       */
      public void mouseEntered( MouseEvent e ) {      }

      /**
       * Unused mouse callback.
       *
       * @param e Event information object.
       */
      public void mouseExited( MouseEvent e ) { }

    /**
     * Unused mouse callback.
     *
     * @param e Event information object.
     */
    public void mouseReleased( MouseEvent e ) { }

    /**
       * Mouse callback for the mouse getting pressed.
       *
       * @param e Event information object.
       */
      public void mousePressed( MouseEvent e ) {

            if ( image == null && invalidAction != null ) {
                  invalidAction.actionPerformed( new ActionEvent( this, 0, null ) );
                  return;
            } // end if

    } // end mousePressed

         /**
       * Unused component event, when the component is hidden.
       *
       * @param e Event information object.
       */
      public void componentHidden( ComponentEvent e ) { }

      /**
       * Unused component event, when the component is moved.
       *
       * @param e Event information object.
       */
      public void componentMoved( ComponentEvent e ) { }

    /**
       * Unused component event, when the component is shown (unhidden).
       *
       * @param e Event information object.
       */
      public void componentShown( ComponentEvent e ) { }

         /**
       * ComponentListener callback for when the component is resized. This causes a new off-screen display area
       * to be allocated and drawn upon.
       *
       * @param e Event information object.
       */
      public void componentResized( ComponentEvent e ) {

            if ( displayImage == null ||
                   getWidth() != displayImage.getWidth( this ) ||
                   getHeight() != displayImage.getHeight( this ) ) {

                  regenerateOffscreenBuffer( getWidth(), getHeight() );
            } // end if

            drawOntoDisplayImage();

      } // end componentResized

    /**
       * Regenerates the buffered image and the graphics context for the buffered image.
       *
       * @param w width of buffered image
       * @param h height of buffered image
       */
      public void regenerateOffscreenBuffer( int w, int h ) {

        displayImage = new BufferedImage( w, h, BufferedImage.TYPE_INT_RGB );
            display = displayImage.createGraphics();

      } // end regenerateOffscreenBuffer

    /**
     * Draws the image onto the offscreen buffer, which is then painted onto
     * the panel.
     */
    public void drawOntoDisplayImage() {

        if ( displayImage == null )
            return;

        if ( image != null ) {

            display.setColor( Color.BLACK );
            display.fill( new Rectangle( 0, 0, getWidth(), getHeight() ) );

            // display the image in the center of the panel
            int x = ( getWidth() - image.getWidth( this ) ) / 2;
            int y = ( getHeight() - image.getHeight( this ) ) / 2;

            display.drawImage( image, x, y, this );

            display.setColor( Color.blue );

        } // end if - else

        repaint();

    } // end drawOntoDisplayImage

    /**
     * Mutator for the image object.
     *
     * @see #image
     */
    public void setImage( Image i ) {

        image = i;

        drawOntoDisplayImage();

    } // end setImage

} // end class
--------------------------------------------------------------------------

Thanks,
Chris
0
 

Author Comment

by:ctjoumas
Comment Utility
Sorry, you can ignore all of the mouse stuff and invalidAction stuff in the ImageContainer class.
0
 
LVL 35

Expert Comment

by:girionis
Comment Utility
 Ok I will try it tomorrow since I do not have time right now :)
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:ctjoumas
Comment Utility
Appreciate it :)

I'm actually seeing something...  in another project me and another guy did, we had the whole layout (and image containers as well) already setup.  So, the regenerateOffscreenBuffer method was always called.  In this case, it is created on the fly - but I don't know why it still isn't called...I think the component should be resized somehow.  I'm a bit unclear about how this works now so I'm looking into it more.
0
 

Author Comment

by:ctjoumas
Comment Utility
So the problem is that the componentResized event is never being fired.  Any idea on why?  Also, when the constructor in ImageContainer is called, i set the dimensions to 250x250, yet when I call the setImage, the width and height are 0.  A solution (although it is a hack) is to call regenearateOffscreenBuffer( 250, 250 )...this fixes the problem, but I don't like how it works.

How can I get the componentResized even to fire or, if that cna't happen, how can I get the width and height to remain 250x250 after it is set in the constructor?

Thanks,
Chris
0
 

Author Comment

by:ctjoumas
Comment Utility
When adding the containers to the panels layout, if I add a "pack()" there (oh, and I also changed the Frame to a JFrame...) it will allow the container to have a width and height, so when I set the image, I can call the regenerateOffscreenBuffer method with getWidth() and getHeight() as parameters.

So, in the main class, the for loop is:

                for ( int i=0; i<images.size(); i++ ) {

                    container = new ImageContainer();

                    int currRow = ( i / 5 ) + 1;
                    int currCol = ( i % 5 ) + 1;

                    panel.add( container, String.valueOf( currCol ) + ", " + String.valueOf( currRow ) + ", f, c" );

                    pack();

                    // set the imageplus object to the first stack
                    displayImage( i );

                    // add the image container object to the vector of image containers
                    containers.add( container );

                }


and in the container classes setImage method, I have

    public void setImage( Image i ) {

        image = i;

        regenerateOffscreenBuffer( getWidth(), getHeight() );

        drawOntoDisplayImage();

    } // end setImage



If there is anyhting wrong with this approach, please let me know!!!

The other problem is still there though... getting the images in the TableLayout to be displayed correctly - I can't tell if they are centered or not... when the window is maximized, it appears to be centered.  I'll try adding a JScrollPane and see what happens.
0
 

Author Comment

by:ctjoumas
Comment Utility
Arrrggg...  nevermind.  The pack forces the component to repaint - so the paintComponent is once again called and tries to paint a null displayImage.  However, if I take that out, the width and height of the ImageContainer panel is 0.  


!!!!!!
0
 
LVL 92

Accepted Solution

by:
objects earned 100 total points
Comment Utility
You cannot generate your image until the frame has a size.
Try just not painting your image if it is null.
   public void paintComponent( Graphics g ) {
       if (displayImage!=null)  g.drawImage( displayImage, 0, 0, getWidth(), getHeight(), this );
    } // end paintComponent
0
 

Author Comment

by:ctjoumas
Comment Utility
I was thinking of doing that too...I'm sure that it would work fine, but I am wondering why the image is null?  I guess that maybe when the frame has a size the componentResized event will be fired, which will in turn create my displayImage?

Well, I'll give it a shot tomorrow.

Thanks!

Chris
0
 
LVL 92

Expert Comment

by:objects
Comment Utility
it's null becuase paintComponent is getting called before you create it :)
0
 

Author Comment

by:ctjoumas
Comment Utility
Ok..that makes sense now.  It is null because it tries painting it before the component is resized...and when the component is resized, the regenerateOffscreenBuffer is called to create the displayImage.

When I load a second file, the component is resized, but the width and height are 0 - so my regenerateOffscreenBuffer is passed 0x0 for width and height, which causes an error.  Should I just add the condition for getWidth() and getHeight() to the already existing conditions to check and make sure it is not 0?  Currently I have:

if ( displayImage == null ||
   getWidth() != displayImage.getWidth( this ) ||
   getHeight() != displayImage.getHeight( this ) ) {

  if ( getWidth() != 0 )
    regenerateOffscreenBuffer( getWidth(), getHeight() );

} // end if

Does it seem ok to add the getWidth() != 0 && getHeight() != 0 there?

If that's it, that should do it for the errors..thanks!  The last thing is the alignment - If i have say 18 images loaded, all I can see is the top left 2 images or so...  if anyone has any suggestions on this, please lemme know!

Thanks again,
Chris
0
 
LVL 92

Expert Comment

by:objects
Comment Utility
> Does it seem ok to add the getWidth() != 0 && getHeight() != 0 there?

y
0
 
LVL 92

Expert Comment

by:objects
Comment Utility
> The last thing is the alignment - If i have say 18 images loaded,
> all I can see is the top left 2 images or so...

Sounds like its related to your layout manager.
0
 

Author Comment

by:ctjoumas
Comment Utility
Ya, I know it is related to my layout manager.  I am using TableLayout from import info.clearthought.layout.TableLayout;

Do you have any idea on how to get this centered?  And also attache it to a scrollpane?  I have been trying that for a bit (it's been a while and I'm gonna start taking another shot at it now), but no luck.  Any idea?  If not, just let me know and I will just close this question up and give out the points.

Thanks,
Chris
0
 
LVL 92

Expert Comment

by:objects
Comment Utility
i've never used it sorry.
To use with scroll pane, just add your component to a scroll pane
JScrollPane pane = new JScrollPane(mycomponent);
0
 

Author Comment

by:ctjoumas
Comment Utility
Thanks for the help.  Also, I already tried the JScrollPane and assumed it just wasn't working - but it only scrolls if the frame is set at a certain width/height...but the even when the images are not all visible, it won't scroll.  I dunno why that is - this layout manager is just a bit strange.

Thanks,
Chris
0
 
LVL 92

Expert Comment

by:objects
Comment Utility
Let me know if you have any more questions :)

http://www.objects.com.au/staff/mick
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

After being asked a question last year, I went into one of my moods where I did some research and code just for the fun and learning of it all.  Subsequently, from this journey, I put together this article on "Range Searching Using Visual Basic.NET …
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now